Dialog creation/sv: Difference between revisions

From FreeCAD Documentation
(Updating to match new version of source page)
(Updating to match new version of source page)
Line 37: Line 37:
pyuic mywidget.ui > mywidget.py
pyuic mywidget.ui > mywidget.py
</syntaxhighlight>
</syntaxhighlight>

Since FreeCAD progressively moved away from PyQt after version 0.13, in favour of [http://qt-project.org/wiki/PySide PySide], to make the file based on PySide now you have to use:
<syntaxhighlight>
pyside-uic mywidget.ui -o mywidget.py
</syntaxhighlight>

På en del system så kallas programmet pyuic4 istället för pyuic. Detta kommer att konvertera .ui filen till ett python skript. Om vi öppnar mywidget.py filen, så är dess innehåll mycket lätt att förstå:
På en del system så kallas programmet pyuic4 istället för pyuic. Detta kommer att konvertera .ui filen till ett python skript. Om vi öppnar mywidget.py filen, så är dess innehåll mycket lätt att förstå:
<syntaxhighlight>
<syntaxhighlight>

Revision as of 20:40, 19 January 2016

På denna sida kommer vi att visa hur man bygger en simpel Qt Dialog med Qt Designer, Qt's officiella verktyg för att designa gränssnitt, och sedan konvertera den till pythonkod, och sedan använda den inuti FreeCAD. Jag antar i exemplet att du redan vet hur du ska redigera och köra python skript, och att du kan göra enkla saker i ett terminalfönster som att navigera, etc. Du måste förstås också ha pyqt installerat.

Designa dialogen

Att i CAD applikationer designa ett bra användargränssnitt är mycket viktigt. Nästan allt som användaren kommer att göra kommer att vara genom någon typ av gränssnitt: läsa dialogrutor, klicka på knappar, välja mellan ikoner, etc. Så det är mycket viktigt att noga tänka igenom vad du vill göra, hur du vill att användaren ska bete sig, och hur arbetsflödet i din aktion kommer att se ut.

Det finns några koncept man bör känna till när man designar ett gränssnitt:

  • Modal/non-modal dialogs: En modal dialog kommer fram längst fram på skärmen, stoppar aktionen i huvudfönstret, och tvingar användare att svara på dialogen, emedan en icke-modal dialog inte stoppar dig från att arbeta med huvudfönstret. I en del fall så är det första bättre, i andra fall inte.
  • Identifiera vad som krävs och vad som är valbart: Försäkra dig om att användaren vet vad den måste göra. Etikettera allting med en riktig beskrivning, använd verktygstips, etc.
  • Separera kommandon från parametrar: Detta görs vanligtvis med knappar och textinmatningsfält. Användaren vet att om en knapp klickas så produceras en aktion emedan ändring av ett värde inuti ett textfält kommer att ändra en parameter någonstans. Nuförtidan så vet de flesta användarna vad en kanpp är, vad ett inmatningsfält är, etc. Det gränssnitts verktygskit vi använder, Qt, är en av de bästa verktygskiten, och vi behöver inte bry oss om så mycket om hur man klargör saker, eftersom de redan är mycket tydliga.

Så, nu när vi har definierat vad vi ska göra, så är det dags att öppna qt designer. Låt oss designa en mycket enkel dialog, som den här:

Vi kommer sedan använda denna dialog i FreeCAD till att producera ett fint rektangulärt plan. Du kanske tycker att det inte är så användbart att producera fina rektangulära plan, men det kommer vara lätt att senare ändra den till att göra mer komplexa saker. När du öppnar det, så ser Qt Designer ut så här:

Det är mycket enkelt att använda. I den vänstra lådan har du element som kan dras till din widget. på den högra sidan har du egenskapspanelerna som visar alla möjliga redigerbara egenskaper på de valda elementen. Så, börja med att skapa en ny widget. Välj "Dialog without buttons", eftersom vi inte vill ha standard Ok/Cancel knappar. Dra sedan3 labels, på din widget, en för titeln, en för att skriva "Höjd" och en för att skriva "Bredd". Labels är enkla texter som syns på din widget, bara för att informera användaren. Om du väljer en label, så kommer det fram flera egenskaper på den högra sidan som du kan ändra om du vill, som teckensnitt, höjd, etc.

Lägg sedan till 2 LineEdits, vilket är textfält som användaren kan fylla i, en för höjden och en för bredden. Här kan vi också redigera egenskaper. Till exempel, varför inte ställa in ett standardvärde? Till exempel 1.00 för varje. På detta sätt, när användaren ser dialogen, så kommer båda värdena redan vara ifyllda och om användaren är nöjd så kan den klicka på knappen direkt, och spara dyrbar tid. Lägg sedan till en PushButton, vilken är den knapp som användaren kommer att behöva klicka på efter att de 2 fälten är ifyllda.

Notera att jag här valde mycket enkla kontroller, men Qt har många fler alternativ, du kan till exempel använda Spinboxes istället för LineEdits, etc... Ta en titt på vad som finns tillgängligt, du kommer säkert att få andra ideer.

Det är ungefär allt vi behöver göra i Qt Designer. En sista sak bara, låt oss döpa om alla våra element till lättare namn, så blir det lättare att identifiera dem i våra skript:

Konvertera vår dialog till python

Låt oss nu spara vår widget någonstans. Den kommar att sparas som en .ui fil, som vi smidigt kan omvandla till python skript med pyuic. på windows, så är pyuic programmet hoppackat med pyqt (ska verifieras), på linux behöver du troligen installera den separat från din pakethanterare (på debian-baserade system, så är det en del av pyqt4-dev-tools paketet). För att göra konverteringen, så behöver du öppna ett terminalfönster (eller ett kommandoprompt fönster på windows), navigera till där du sparade din .ui file, och skriva:

pyuic mywidget.ui > mywidget.py

Since FreeCAD progressively moved away from PyQt after version 0.13, in favour of PySide, to make the file based on PySide now you have to use:

pyside-uic mywidget.ui -o mywidget.py

På en del system så kallas programmet pyuic4 istället för pyuic. Detta kommer att konvertera .ui filen till ett python skript. Om vi öppnar mywidget.py filen, så är dess innehåll mycket lätt att förstå:

from PySide import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(187, 178)
        self.title = QtGui.QLabel(Dialog)
        self.title.setGeometry(QtCore.QRect(10, 10, 271, 16))
        self.title.setObjectName("title")
        self.label_width = QtGui.QLabel(Dialog)
        ...

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

   def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.title.setText(QtGui.QApplication.translate("Dialog", "Plane-O-Matic", None, QtGui.QApplication.UnicodeUTF8))
        ...

Som du ser så har det en mycket enkel struktur: En klass benämnd Ui_Dialog skapas, som sparar din widgets gränssnittselement. Den klassen har två metoder, en fär att ställa in widgeten, och en för att översätta dess innehåll, som är en del av de allmäna Qt mekanismerna för översättning av gränssnittselement. Inställningsmetoden skapar, en och en, widgetarna som vi har definierat dem i Qt Designer, och sätter deras alternativ som vi bestämt tidigare. Sedan blir hela gränssnittet översatt, och slutligen, blir sloten anslutna (vi pratar om det senare).

Vi kan nu skapa en ny widget, och använda denna klass till att skapa dess gränssnitt. Vi kan redan se vår widget i aktion, genom att sätta vår mywidget.py fil på en plats där FreeCAD kommer att hitta den (i FreeCAD's bin katalog, eller i någon av underkatalogerna till Mod ), och i FreeCAD pythontolken skriva:

from PySide import QtGui
import mywidget
d = QtGui.QWidget()
d.ui = mywidget.Ui_Dialog()
d.ui.setupUi(d)
d.show()

Och vår dialog kommer fram! Notera att din pythontolk fortfarande fungerar, vi har en icke-modal dialog. Så, för att stänga den, så kan vi (förutom att klicka på dess stängningsikon, förstås) skriva:

d.hide()

Ordna så att vår dialog gör något

Nu när vi kan visa och gömma vår dialog, så behöver vi bara lägga till en sista bit: Att låta den göra något! Om du leker lite med Qt designer, så kommer du snabbt upptäcka ett helt avsnitt som kallas "signals and slots". I grunden så fungerar det så här: element på dina widgetar (i Qt terminologi, så är dessa element widgetar själva) kan sända signaler. Dessa signaler skiljer sig beroende på widget typ. Till exempel, en knapp kan sända en signal när den är nedtryckt och när den släpps. Dessa signaler kan anslutas till slots, vilka kan vara en speciell funktionalitet i andra widgetar (till exempel en dialog har en "stäng" slot till vilken du kan ansluta signalen från en stäng knapp), eller kan vara anpassade funktioner. PyQt Referensdokumentation listar alla qt widgetar, vad de kan göra, vilka signaler de kan sända , etc...

Vad vi kommer att göra här, är att skapa en ny funktion som kommer att skapa ett plan, baserat på höjd och bredd, och ansluta denna funktion till nedtryckt signalen som sänds av vår "Skapa!" button. Så, låt os börja med att importera våra FreeCAD moduler, genom att sätta följande rader i toppen på skriptet, där vi redan har importerat QtCore och QtGui:

import FreeCAD, Part

Låt oss sedan lägga till en ny funktion till vår Ui_Dialog klass:

def createPlane(self):
    try:
        # first we check if valid numbers have been entered
        w = float(self.width.text())
        h = float(self.height.text())
    except ValueError:
        print "Error! Width and Height values must be valid numbers!"
    else:
        # create a face from 4 points
        p1 = FreeCAD.Vector(0,0,0)
        p2 = FreeCAD.Vector(w,0,0)
        p3 = FreeCAD.Vector(w,h,0)
        p4 = FreeCAD.Vector(0,h,0)
        pointslist = [p1,p2,p3,p4,p1]
        mywire = Part.makePolygon(pointslist)
        myface = Part.Face(mywire)
        Part.show(myface)
        self.hide()

Sedan behöver vi informera Qt att ansluta knappen till funktionen, genom att placera följande rad precis innan QtCore.QMetaObject.connectSlotsByName(Dialog):

QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)

Detta ansluter, som du ser, pressed() signalen från vårt skapade objekt ("Skapa!" knappen), till en slot benämnd createPlane, som vi just definierade. Klart! Nu, som en slutlig justering, så kan vi lägga till lite funktion för att skapa dialogen, så kommer den bli lättare att anropa. Utanför Ui_Dialog klassan, så lägger vi till denna kod:

class plane():
   def __init__(self):
       self.d = QtGui.QWidget()
       self.ui = Ui_Dialog()
       self.ui.setupUi(self.d)
       self.d.show()

(Python reminder: the __init__ method of a class is automatically executed whenever a new object is created!)

Det enda vi sedan behöver göra från FreeCAD är:

import mywidget
myDialog = mywidget.plane()

Det var allt. Nu kan du försöka andra saker, som till exempel sätta in din widget i FreeCAD's gränssnitt (se kodbitar sidan), eller göra mycket mer avancerade verktyg, genom att använda andra element på din widget.

Det kompletta skriptet

För referens, så är det kompletta skriptet här:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'mywidget.ui'
#
# Created: Mon Jun  1 19:09:10 2009
#      by: PyQt4 UI code generator 4.4.4
# Modified for PySide 16:02:2015 
# WARNING! All changes made in this file will be lost!

from PySide import QtCore, QtGui
import FreeCAD, Part 

class Ui_Dialog(object):
   def setupUi(self, Dialog):
       Dialog.setObjectName("Dialog")
       Dialog.resize(187, 178)
       self.title = QtGui.QLabel(Dialog)
       self.title.setGeometry(QtCore.QRect(10, 10, 271, 16))
       self.title.setObjectName("title")
       self.label_width = QtGui.QLabel(Dialog)
       self.label_width.setGeometry(QtCore.QRect(10, 50, 57, 16))
       self.label_width.setObjectName("label_width")
       self.label_height = QtGui.QLabel(Dialog)
       self.label_height.setGeometry(QtCore.QRect(10, 90, 57, 16))
       self.label_height.setObjectName("label_height")
       self.width = QtGui.QLineEdit(Dialog)
       self.width.setGeometry(QtCore.QRect(60, 40, 111, 26))
       self.width.setObjectName("width")
       self.height = QtGui.QLineEdit(Dialog)
       self.height.setGeometry(QtCore.QRect(60, 80, 111, 26))
       self.height.setObjectName("height")
       self.create = QtGui.QPushButton(Dialog)
       self.create.setGeometry(QtCore.QRect(50, 140, 83, 26))
       self.create.setObjectName("create")

       self.retranslateUi(Dialog)
       QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)
       QtCore.QMetaObject.connectSlotsByName(Dialog)

   def retranslateUi(self, Dialog):
       Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
       self.title.setText(QtGui.QApplication.translate("Dialog", "Plane-O-Matic", None, QtGui.QApplication.UnicodeUTF8))
       self.label_width.setText(QtGui.QApplication.translate("Dialog", "Width", None, QtGui.QApplication.UnicodeUTF8))
       self.label_height.setText(QtGui.QApplication.translate("Dialog", "Height", None, QtGui.QApplication.UnicodeUTF8))
       self.create.setText(QtGui.QApplication.translate("Dialog", "Create!", None, QtGui.QApplication.UnicodeUTF8))

   def createPlane(self):
       try:
           # first we check if valid numbers have been entered
           w = float(self.width.text())
           h = float(self.height.text())
       except ValueError:
           print "Error! Width and Height values must be valid numbers!"
       else:
           # create a face from 4 points
           p1 = FreeCAD.Vector(0,0,0)
           p2 = FreeCAD.Vector(w,0,0)
           p3 = FreeCAD.Vector(w,h,0)
           p4 = FreeCAD.Vector(0,h,0)
           pointslist = [p1,p2,p3,p4,p1]
           mywire = Part.makePolygon(pointslist)
           myface = Part.Face(mywire)
           Part.show(myface)

class plane():
   def __init__(self):
       self.d = QtGui.QWidget()
       self.ui = Ui_Dialog()
       self.ui.setupUi(self.d)
       self.d.show()

Creation of a dialog with buttons

Method 1

An example of a dialog box complete with its connections.

# -*- coding: utf-8 -*-
# Create by flachyjoe

from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


class Ui_MainWindow(object):

     def __init__(self, MainWindow):
        self.window = MainWindow

        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))

        self.pushButton = QtGui.QPushButton(self.centralWidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.on_pushButton_clicked) #connection pushButton

        self.lineEdit = QtGui.QLineEdit(self.centralWidget)
        self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.lineEdit.returnPressed.connect(self.on_lineEdit_clicked) #connection lineEdit

        self.checkBox = QtGui.QCheckBox(self.centralWidget)
        self.checkBox.setGeometry(QtCore.QRect(30, 90, 81, 20))
        self.checkBox.setChecked(True)
        self.checkBox.setObjectName(_fromUtf8("checkBoxON"))
        self.checkBox.clicked.connect(self.on_checkBox_clicked) #connection checkBox

        self.radioButton = QtGui.QRadioButton(self.centralWidget)
        self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        self.radioButton.clicked.connect(self.on_radioButton_clicked) #connection radioButton

        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        MainWindow.setMenuBar(self.menuBar)

        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)

        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)

     def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        self.pushButton.setText(_translate("MainWindow", "OK", None))
        self.lineEdit.setText(_translate("MainWindow", "tyty", None))
        self.checkBox.setText(_translate("MainWindow", "CheckBox", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))

     def on_checkBox_clicked(self):
        if self.checkBox.checkState()==0:
            App.Console.PrintMessage(str(self.checkBox.checkState())+"  CheckBox KO\r\n")
        else:     
            App.Console.PrintMessage(str(self.checkBox.checkState())+" CheckBox OK\r\n")
#        App.Console.PrintMessage(str(self.lineEdit.setText("tititi"))+" LineEdit\r\n") #write text to the lineEdit window !
#        str(self.lineEdit.setText("tititi")) #écrit le texte dans la fenêtre lineEdit
        App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit\r\n")

     def on_radioButton_clicked(self):
        if self.radioButton.isChecked():
             App.Console.PrintMessage(str(self.radioButton.isChecked())+" Radio OK\r\n")
        else:
             App.Console.PrintMessage(str(self.radioButton.isChecked())+"  Radio KO\r\n")

     def on_lineEdit_clicked(self):
#        if self.lineEdit.textChanged():
		    App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")

     def on_pushButton_clicked(self):
        App.Console.PrintMessage("Terminé\r\n")
        self.window.hide()

MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()

Here the same window but with an icon on each button.

Download associated icons (Click rigth "Copy the image below ...)"

# -*- coding: utf-8 -*-

from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


class Ui_MainWindow(object):

     def __init__(self, MainWindow):
        self.window = MainWindow
        path = FreeCAD.ConfigGet("UserAppData")
#        path = FreeCAD.ConfigGet("AppHomePath")

        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(400, 300)
        self.centralWidget = QtGui.QWidget(MainWindow)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))

        self.pushButton = QtGui.QPushButton(self.centralWidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton.clicked.connect(self.on_pushButton_clicked) #connection pushButton

        self.lineEdit = QtGui.QLineEdit(self.centralWidget)
        self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
        self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
        self.lineEdit.returnPressed.connect(self.on_lineEdit_clicked) #connection lineEdit

        self.checkBox = QtGui.QCheckBox(self.centralWidget)
        self.checkBox.setGeometry(QtCore.QRect(30, 90, 100, 20))
        self.checkBox.setChecked(True)
        self.checkBox.setObjectName(_fromUtf8("checkBoxON"))
        self.checkBox.clicked.connect(self.on_checkBox_clicked) #connection checkBox

        self.radioButton = QtGui.QRadioButton(self.centralWidget)
        self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
        self.radioButton.setObjectName(_fromUtf8("radioButton"))
        self.radioButton.clicked.connect(self.on_radioButton_clicked) #connection radioButton

        MainWindow.setCentralWidget(self.centralWidget)

        self.menuBar = QtGui.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 26))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        MainWindow.setMenuBar(self.menuBar)

        self.mainToolBar = QtGui.QToolBar(MainWindow)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)

        self.statusBar = QtGui.QStatusBar(MainWindow)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)

        # Affiche un icone sur le bouton PushButton
        # self.image_01 = "C:\Program Files\FreeCAD0.13\Icone01.png" # adapt the icon name
        self.image_01 = path+"Icone01.png" # adapt the name of the icon
        icon01 = QtGui.QIcon() 
        icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon01) 
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

        # Affiche un icone sur le bouton RadioButton 
        # self.image_02 = "C:\Program Files\FreeCAD0.13\Icone02.png" # adapt the name of the icon
        self.image_02 = path+"Icone02.png" # adapter le nom de l'icone
        icon02 = QtGui.QIcon() 
        icon02.addPixmap(QtGui.QPixmap(self.image_02),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.radioButton.setIcon(icon02) 
        # self.radioButton.setLayoutDirection(QtCore.Qt.RightToLeft) #  This command reverses the direction of the button

        # Affiche un icone sur le bouton CheckBox 
        # self.image_03 = "C:\Program Files\FreeCAD0.13\Icone03.png" # the name of the icon
        self.image_03 = path+"Icone03.png" # adapter le nom de l'icone
        icon03 = QtGui.QIcon() 
        icon03.addPixmap(QtGui.QPixmap(self.image_03),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.checkBox.setIcon(icon03) 
        # self.checkBox.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button


     def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "FreeCAD", None))
        self.pushButton.setText(_translate("MainWindow", "OK", None))
        self.lineEdit.setText(_translate("MainWindow", "tyty", None))
        self.checkBox.setText(_translate("MainWindow", "CheckBox", None))
        self.radioButton.setText(_translate("MainWindow", "RadioButton", None))

     def on_checkBox_clicked(self):
        if self.checkBox.checkState()==0:
            App.Console.PrintMessage(str(self.checkBox.checkState())+"  CheckBox KO\r\n")
        else:     
            App.Console.PrintMessage(str(self.checkBox.checkState())+" CheckBox OK\r\n")
           # App.Console.PrintMessage(str(self.lineEdit.setText("tititi"))+" LineEdit\r\n") # write text to the lineEdit window !
           # str(self.lineEdit.setText("tititi")) #écrit le texte dans la fenêtre lineEdit
        App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit\r\n")

     def on_radioButton_clicked(self):
        if self.radioButton.isChecked():
             App.Console.PrintMessage(str(self.radioButton.isChecked())+" Radio OK\r\n")
        else:
             App.Console.PrintMessage(str(self.radioButton.isChecked())+"  Radio KO\r\n")

     def on_lineEdit_clicked(self):
          # if self.lineEdit.textChanged():
          App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")

     def on_pushButton_clicked(self):
        App.Console.PrintMessage("Terminé\r\n")
        self.window.hide()

MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow(MainWindow)
MainWindow.show()

Here the code to display the icon on the pushButton, change the name for another button, (radioButton, checkBox) and the path to the icon.

        # Affiche un icône sur le bouton PushButton
        # self.image_01 = "C:\Program Files\FreeCAD0.13\icone01.png" # the name of the icon
        self.image_01 = path+"icone01.png" # the name of the icon
        icon01 = QtGui.QIcon() 
        icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.pushButton.setIcon(icon01) 
        self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

The command UserAppData gives the user path AppHomePath gives the installation path of FreeCAD

#        path = FreeCAD.ConfigGet("UserAppData")
        path = FreeCAD.ConfigGet("AppHomePath")

This command reverses the horizontal button, right to left.

self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button

Method 2

Another method to display a window, here by creating a file QtForm.py which contains the header program (module called with import QtForm), and a second module that contains the code window all these accessories, and your code (the calling module).

This method requires two separate files, but allows to shorten your program using the file ' ' QtForm.py ' ' import. Then distribute the two files together, they are inseparable.

The file QtForm.py

# -*- coding: utf-8 -*-
# Create by flachyjoe
from PySide import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
   def _fromUtf8(s):
      return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
      return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
   def _translate(context, text, disambig):
      return QtGui.QApplication.translate(context, text, disambig)

class Form(object):
   def __init__(self, title, width, height):
      self.window = QtGui.QMainWindow()
      self.title=title
      self.window.setObjectName(_fromUtf8(title))
      self.window.setWindowTitle(_translate(self.title, self.title, None))
      self.window.resize(width, height)

   def show(self):
      self.createUI()
      self.retranslateUI()
      self.window.show()
   
   def setText(self, control, text):
      control.setText(_translate(self.title, text, None))

The appellant, file that contains the window and your code.

The file my_file.py

The connections are to do, a good exercise.

# -*- coding: utf-8 -*-
# Create by flachyjoe
from PySide import QtCore, QtGui
import QtForm

class myForm(QtForm.Form):
   def createUI(self):
      self.centralWidget = QtGui.QWidget(self.window)
      self.window.setCentralWidget(self.centralWidget)
      
      self.pushButton = QtGui.QPushButton(self.centralWidget)
      self.pushButton.setGeometry(QtCore.QRect(30, 170, 93, 28))
      self.pushButton.clicked.connect(self.on_pushButton_clicked)
      
      self.lineEdit = QtGui.QLineEdit(self.centralWidget)
      self.lineEdit.setGeometry(QtCore.QRect(30, 40, 211, 22))
      
      self.checkBox = QtGui.QCheckBox(self.centralWidget)
      self.checkBox.setGeometry(QtCore.QRect(30, 90, 81, 20))
      self.checkBox.setChecked(True)
      
      self.radioButton = QtGui.QRadioButton(self.centralWidget)
      self.radioButton.setGeometry(QtCore.QRect(30, 130, 95, 20))
   
   def retranslateUI(self):
      self.setText(self.pushButton, "Fermer")
      self.setText(self.lineEdit, "essai de texte")
      self.setText(self.checkBox, "CheckBox")
      self.setText(self.radioButton, "RadioButton")
   
   def on_pushButton_clicked(self):
      self.window.hide()

myWindow=myForm("Fenêtre de test",400,300)
myWindow.show()

Other example

Are treated :

  1. icon for window
  2. horizontalSlider
  3. progressBar horizontal
  4. verticalSlider
  5. progressBar vertical
  6. lineEdit
  7. lineEdit
  8. doubleSpinBox
  9. doubleSpinBox
  10. doubleSpinBox
  11. buttom
  12. buttom
  13. radioButtom with icons
  14. checkBox with icon checked and unchecked
  15. textEdit
  16. graphicsView with 2 graphes

The code page and the icons Qt_Example

Some useful commands

# Here the code to display the icon on the '''pushButton''', 
# change the name to another button, ('''radioButton, checkBox''') as well as the path to the icon,

       # Displays an icon on the button PushButton
       # self.image_01 = "C:\Program Files\FreeCAD0.13\icone01.png" # he name of the icon
       self.image_01 = path+"icone01.png" # the name of the icon
       icon01 = QtGui.QIcon() 
       icon01.addPixmap(QtGui.QPixmap(self.image_01),QtGui.QIcon.Normal, QtGui.QIcon.Off)
       self.pushButton.setIcon(icon01) 
       self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button


# path = FreeCAD.ConfigGet("UserAppData") # gives the user path
  path = FreeCAD.ConfigGet("AppHomePath") # gives the installation path of FreeCAD

# This command reverses the horizontal button, right to left
self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the horizontal button

# Displays an info button
self.pushButton.setToolTip(_translate("MainWindow", "Quitter la fonction", None)) # Displays an info button

# This function gives a color button
self.pushButton.setStyleSheet("background-color: red") # This function gives a color button

# This function gives a color to the text of the button
self.pushButton.setStyleSheet("color : #ff0000") # This function gives a color to the text of the button

# combinaison des deux, bouton et texte
self.pushButton.setStyleSheet("color : #ff0000; background-color : #0000ff;" ) #  combination of the two, button, and text

# replace the icon in the main window
MainWindow.setWindowIcon(QtGui.QIcon('C:\Program Files\FreeCAD0.13\View-C3P.png'))

# connects a lineEdit on execute
self.lineEdit.returnPressed.connect(self.execute) # connects a lineEdit on "def execute" after validation on enter
# self.lineEdit.textChanged.connect(self.execute) # connects a lineEdit on "def execute" with each keystroke on the keyboard

# display text in a lineEdit
self.lineEdit.setText(str(val_X)) # Displays the value in the lineEdit (convert to string)

# extract the string contained in a lineEdit
 val_X = self.lineEdit.text() # extract the (string) string contained in lineEdit
 val_X = float(val_X0)        # converted the string to an floating
 val_X = int(val_X0)          # convert the string to an integer

# This code allows you to change the font and its attributes
       font = QtGui.QFont()
       font.setFamily("Times New Roman")
       font.setPointSize(10)
       font.setWeight(10)
       font.setBold(True) # same result with tags "<b>your text</b>" (in quotes)
       self.label_6.setFont(font)
       self.label_6.setObjectName("label_6")
       self.label_6.setStyleSheet("color : #ff0000") # This function gives a color to the text
       self.label_6.setText(_translate("MainWindow", "Select a view", None))

By using the characters with accents, where you get the error :

Several solutions are possible.

UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data

# conversion from a lineEdit
App.activeDocument().CopyRight.Text = str(unicode(self.lineEdit_20.text() , 'ISO-8859-1').encode('UTF-8'))
DESIGNED_BY = unicode(self.lineEdit_01.text(), 'ISO-8859-1').encode('UTF-8')

or with the procedure

def utf8(unio):
    return unicode(unio).encode('UTF8')

UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 9: ordinal not in range(128)

# conversion
a = u"Nom de l'élément : "
f.write('''a.encode('iso-8859-1')'''+str(element_)+"\n")

or with the procedure

def iso8859(encoder):
    return unicode(encoder).encode('iso-8859-1')

or

iso8859(unichr(176))

or

unichr(ord(176))

or

uniteSs = "mm"+iso8859(unichr(178))
print unicode(uniteSs, 'iso8859')


Line drawing function/sv
Licence/sv