Dialog creation/es: Difference between revisions

From FreeCAD Documentation
(Updating to match new version of source page)
(Updating to match new version of source page)
Line 27: Line 27:


[[Image:Qtpropeditor.jpg]]
[[Image:Qtpropeditor.jpg]]

== Convertir nuestro diálogo a Python ==
== Convertir nuestro diálogo a Python ==

Ahora, vamos a salvar nuestro widget en alguna parte. Se guardará como un archivo .ui, que fácilmente se convertirá en un archivo de guión de Python por medio de pyuic. En Windows, el programa pyuic se ve enriquecido con PyQt (por verificar), en linux es probable que tengas que instalarlo por separado desde tu gestor de paquetes (en sistemas basados en Debian, es parte del paquete de herramientas PyQt4-dev-tools). Para realizar la conversión, tendrás que abrir una ventana de terminal (o una ventana de símbolo de sistema en Windows), ve a donde guardaste el archivo .ui, y escribe:
Ahora, vamos a salvar nuestro widget en alguna parte. Se guardará como un archivo .ui, que fácilmente se convertirá en un archivo de guión de Python por medio de pyuic. En Windows, el programa pyuic se ve enriquecido con PyQt (por verificar), en linux es probable que tengas que instalarlo por separado desde tu gestor de paquetes (en sistemas basados en Debian, es parte del paquete de herramientas PyQt4-dev-tools). Para realizar la conversión, tendrás que abrir una ventana de terminal (o una ventana de símbolo de sistema en Windows), ve a donde guardaste el archivo .ui, y escribe:
<syntaxhighlight>
<syntaxhighlight>
pyuic mywidget.ui > mywidget.py
pyuic mywidget.ui > mywidget.py
</syntaxhighlight>
</syntaxhighlight>
Into Windows pyuic.py are located in "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py"
For create batch file "compQt4.bat:
<syntaxhighlight>
@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py
</syntaxhighlight>
In the console Dos type without extension
<syntaxhighlight>
compQt4 myUiFile
</syntaxhighlight>
Into Linux : to do

<!--T:55-->
Since FreeCAD progressively moved away from PyQt after version 0.13, in favour of [http://qt-project.org/wiki/PySide PySide] (Choice your PySide install [http://pyside.readthedocs.org/en/latest/building/ building PySide]), to make the file based on PySide now you have to use:


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>
<syntaxhighlight>
pyside-uic mywidget.ui -o mywidget.py
pyside-uic mywidget.ui -o mywidget.py
</syntaxhighlight>
</syntaxhighlight>
Into Windows uic.py are located in "C:\Python27\Lib\site-packages\PySide\scripts\uic.py"
For create batch file "compSide.bat":
<syntaxhighlight>
@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py
</syntaxhighlight>
In the console Dos type without extension
<syntaxhighlight>
compSide myUiFile
</syntaxhighlight>
Into Linux : to do



En algunos sistemas el programa se llama pyuic4 en lugar de pyuic. Esta operación simplemente convertirá el archivo .ui en un archivo de guión de Python. Si abrimos el archivo mywidget.py, su contenido es muy fácil de entender:
En algunos sistemas el programa se llama pyuic4 en lugar de pyuic. Esta operación simplemente convertirá el archivo .ui en un archivo de guión de Python. Si abrimos el archivo mywidget.py, su contenido es muy fácil de entender:
Line 300: Line 321:
def on_lineEdit_clicked(self):
def on_lineEdit_clicked(self):
# if self.lineEdit.textChanged():
# if self.lineEdit.textChanged():
App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")
App.Console.PrintMessage(str(self.lineEdit.displayText())+" LineEdit Display\r\n")


def on_pushButton_clicked(self):
def on_pushButton_clicked(self):
Line 549: Line 570:
self.window.hide()
self.window.hide()


myWindow=myForm("Fenêtre de test",400,300)
myWindow=myForm("Fenetre de test",400,300)
myWindow.show()
myWindow.show()
</syntaxhighlight>
</syntaxhighlight>
Line 582: Line 603:
The code page and the icons [[Qt_Example|Qt_Example]]
The code page and the icons [[Qt_Example|Qt_Example]]


==Use QFileDialog for write the file==
Complete code:
<syntaxhighlight>
# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

try:
SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Save a file txt"),path, "*.txt") # PyQt4
# "here the text displayed on windows" "here the filter (extension)"
except Exception:
SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path, "*.txt") # PySide
# "here the text displayed on windows" "here the filter (extension)"
if SaveName == "": # if the name file are not selected then Abord process
App.Console.PrintMessage("Process aborted"+"\n")
else: # if the name file are selected or created then
App.Console.PrintMessage("Registration of "+SaveName+"\n") # text displayed to Report view (Menu > View > Report view checked)
try: # detect error ...
file = open(SaveName, 'w') # open the file selected to write (w) # (wb is binary)
try: # if error detected to write ...
# here your code
print "here your code"
file.write(str(1)+"\n") # write the number convert in text with (str())
file.write("FreeCAD the best") # write the the text with (" ")
finally: # if error detected to write ... or not the file is closed
file.close() # if error detected to write ... or not the file is closed
except Exception:
App.Console.PrintError("Error Registration file "+SaveName+"\n") # detect error ... display the text in red (PrintError)

</syntaxhighlight>
==Use QFileDialog for read the file==
Complete code:
<syntaxhighlight>
# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

OpenName = ""
try:
OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Read a file txt"),path, "*.txt") # PyQt4
# "here the text displayed on windows" "here the filter (extension)"
except Exception:
OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a file txt", path, "*.txt")#PySide
# "here the text displayed on windows" "here the filter (extension)"
if OpenName == "": # if the name file are not selected then Abord process
App.Console.PrintMessage("Process aborted"+"\n")
else:
App.Console.PrintMessage("Read "+OpenName+"\n") # text displayed to Report view (Menu > View > Report view checked)
try: # detect error to read file
file = open(OpenName, "r") # open the file selected to read (r) # (rb is binary)
try: # detect error ...
op = OpenName.split("/") # decode the path
op2 = op[-1].split(".") # decode the file name
nomF = op2[0] # the file name are isolated

App.Console.PrintMessage(str(nomF)+"\n") # the file name are displayed

for ligne in file: # read the file
X = ligne.rstrip('\n\r') #.split() # decode the line
print X # print the line in report view other method
# (Menu > Edit > preferences... > Output window > Redirect internal Python output (and errors) to report view checked)
finally: # if error detected to read ... or not error the file is closed
file.close() # if error detected to read ... or not error the file is closed
except Exception: # if one error detected to read file
App.Console.PrintError("Error in reading the file "+OpenName+"\n") # if one error detected ... display the text in red (PrintError)

</syntaxhighlight>
==Use QColorDialog for get the color==
Complete code:
<syntaxhighlight>
# -*- coding: utf-8 -*-
# https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QColor.html
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

couleur = QtGui.QColorDialog.getColor()
if couleur.isValid():
red = int(str(couleur.name()[1:3]),16) # decode hexadecimal to int()
green = int(str(couleur.name()[3:5]),16) # decode hexadecimal to int()
blue = int(str(couleur.name()[5:7]),16) # decode hexadecimal to int()

print couleur #
print "hexadecimal ",couleur.name() # color format hexadecimal mode 16
print "Red color ",red # color format decimal
print "Green color ",green # color format decimal
print "Blue color ",blue # color format decimal

</syntaxhighlight>
==Some useful commands==
==Some useful commands==
<syntaxhighlight>
<syntaxhighlight>

Revision as of 14:08, 24 March 2016

En esta página vamos a mostrar cómo crear un simple letrero de diálogo con Qt Designer, la herramienta oficial de Qt para el diseño de interfaces, después lo convertiremos en código de Python, para luego utilizarlo en FreeCAD. Vamos a suponer en el ejemplo que ya sabes cómo editar y ejecutar archivos de guión de Python, y que puedes hacer cosas simples en una ventana de terminal, como navegar, etc. También debes tener, por supuesto, PyQt instalado.

En las aplicaciones de CAD, el diseño de una buena interfaz de usuario (UI, User Interface) es muy importante. Casi todo lo que el usuario haga será a través de alguna parte de la interfaz: leyendo los letreros de diálogo, pulsando los botones, eligiendo entre iconos, etc. Así que es muy importante pensar cuidadosamente lo que quieres hacer, cómo deseas que el usuario se comporte, y cómo será el flujo de trabajo de tu acción.

Hay un par de conceptos que debes saber a la hora de diseñar la interfaz:

  • Letreros de diálogo Modales/no modales: Un letrero de diálogo modal aparece delante de la pantalla, deteniendo la acción de la ventana principal, obligando al usuario a responder al cuadro de diálogo, mientras que un cuadro de diálogo no modal permite seguir trabajando en la ventana principal. En algunos casos la primera opción es mejor, pero en otros casos no.
  • Identificación de lo que es necesario y lo que es opcional: Asegúrate de que el usuario sabe lo que debe hacer. Etiqueta todo con la descripción adecuada, utiliza etiquetas de información sobre el uso de las herramientas, etc.
  • Separar los comandos de los parámetros: Esto se hace generalmente con botones y cuadros de texto. El usuario sabe que al hacer clic en un botón, se produce una acción mientras que al cambiar un valor dentro de un cuadro de texto va a cambiar un parámetro en alguna parte. Hoy en día, sin embargo, los usuarios suelen conocer bien lo que es un botón, lo que es un cuadro de texto, etc. El conjunto de herramientas de interfaz que está utilizando, Qt, es el conjunto de herramientas más avanzado, y no tendrás que preocuparte mucho de hacer las cosas claras, puesto que ya va a ser muy clara por sí misma.

Así que, ahora que tenemos bien definido lo que haremos, es el momento para abrir el diseñador de Qt Designer. Diseñemos un letrero de diálogo muy sencillo, como este:

Después podremos utilizar este letrero de diálogo en FreeCAD para producir un bonito plano rectangular. Puede que no veas muy útil hacer planos rectangulares, pero será fácil cambiarlo más adelante para hacer cosas más complejas. Cuando lo abras, el aspecto de Qt Designer es el siguiente:

Es muy sencillo de utilizar. En la barra de la izquierda tienes elementos que pueden ser arrastrados a tu widget. En el lado derecho tienes los paneles de propiedades mostrando todo tipo de propiedades editables de los elementos seleccionados. Comencemos ahora con la creación de un nuevo widget o complemento. Selecciona "letrero de diálogo sin botones", ya que no queremos el formato predeterminado de botones Ok/Cancelar. A continuación, arrastra sobre tu widget 3 etiquetas, una para el título, una para escribir "Altura" y otra para escribir "Ancho". Las etiquetas son textos sencillos que aparecen en tu widget, simplemente para informar al usuario. Si seleccionas una etiqueta, en la parte derecha aparecerán varias propiedades que puedes cambiar si lo deseas, como el estilo de fuente, altura, etc.

A continuación, agrega 2 LineEdits, que son cuadros de texto que el usuario puede rellenar, uno para la altura y uno para el ancho. También en este caso, podemos editar las propiedades. Por ejemplo, ¿por qué no establecer un valor predeterminado? digamos 1.00 para cada uno. De esta manera, cuando el usuario vea el letrero de diálogo, ambos campos ya estarán rellenados, y si está conforme puede pulsar el botón directamente, ahorrando un tiempo precioso. A continuación, agrega un PushButton, que es el botón que el usuario deberá pulsar después de llenar los 2 campos.

Ten en cuenta que he elegido aquí controles muy sencillos, pero Qt tiene muchas más opciones, por ejemplo, podría utilizar Spinboxes en lugar de LineEdits, etc. Echa un vistazo a lo que está disponible, seguramente tendrás otras ideas.

Eso es prácticamente todo lo que necesitamos hacer en Qt Designer. Una última cosa, sin embargo, vamos a cambiar el nombre de todos nuestros elementos con nombres más adecuados, de modo que sea más fácil identificarlos en nuestros archivos de guión:

Convertir nuestro diálogo a Python

Ahora, vamos a salvar nuestro widget en alguna parte. Se guardará como un archivo .ui, que fácilmente se convertirá en un archivo de guión de Python por medio de pyuic. En Windows, el programa pyuic se ve enriquecido con PyQt (por verificar), en linux es probable que tengas que instalarlo por separado desde tu gestor de paquetes (en sistemas basados en Debian, es parte del paquete de herramientas PyQt4-dev-tools). Para realizar la conversión, tendrás que abrir una ventana de terminal (o una ventana de símbolo de sistema en Windows), ve a donde guardaste el archivo .ui, y escribe:

pyuic mywidget.ui > mywidget.py

Into Windows pyuic.py are located in "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" For create batch file "compQt4.bat:

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py

In the console Dos type without extension

compQt4 myUiFile

Into Linux : to do

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

pyside-uic mywidget.ui -o mywidget.py

Into Windows uic.py are located in "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" For create batch file "compSide.bat":

@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py

In the console Dos type without extension

compSide myUiFile

Into Linux : to do


En algunos sistemas el programa se llama pyuic4 en lugar de pyuic. Esta operación simplemente convertirá el archivo .ui en un archivo de guión de Python. Si abrimos el archivo mywidget.py, su contenido es muy fácil de entender:

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))
        ...

Como verás, tiene una estructura muy simple: se crea una clase denominada Ui_Dialog, que almacena los elementos de interfaz de nuestro widget o complemento. Esa clase tiene dos métodos, uno para la configuración del widget, y otro para la traducción de su contenido, eso es parte del mecanismo general de Qt para la traducción de elementos de la interfaz. El método de configuración simplemente crea, uno a uno, los widgets tal como los has definido en Qt Designer, y establece sus opciones, como hayamos decidido con anterioridad. Despues, toda la interfaz se traduce, y por último, se conectan las ranuras (slots) (hablaremos de eso más adelante).

Ahora podemos crear un nuevo widget, y utilizar esta clase para crear su interfaz. Ya podemos ver nuestro widget en acción, poniendo nuestro archivo mywidget.py en un lugar donde FreeCAD lo encuentre (en el directorio bin de FreeCAD, o en cualquiera de los subdirectorios Mod), y, en el intérprete de Python FreeCAD, ejecutamos:

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

¡Y nuestro letrero de diálogo aparecerá! Ten en cuenta que nuestro intérprete de Python todavía está trabajando, ya que hemos usado un letrero de diálogo no modal. Por lo tanto, para cerrarlo, podemos (aparte de hacer clic en el icono de cerrar, por supuesto) escribir:

d.hide()

Ahora que podemos mostrar y ocultar nuestro letrero de diálogo, sólo tenemos que añadir una última parte: ¡que haga algo! Si juegas un poco con Qt Designer, descubrirás rápidamente toda una sección llamada "señales y slots". Básicamente, funciona así: los elementos de los widgets o complementos (en la terminología de Qt, estos elementos son a su vez widgets) pueden enviar señales. Estas señales varían según el tipo de widget. Por ejemplo, un botón puede enviar una señal cuando se presiona y cuando es soltado. Estas señales se pueden conectar a los slots, que puede ser una funcionalidad especial de otros widgets (por ejemplo, un cuadro de diálogo tiene un slot "close" (cerrado) en el que se puede conectar la señal de un botón close (de cierre)), o pueden ser funciones de usuario. La Documentación de referencia de PyQt enumera todos los widgets Qt, lo que pueden hacer, que señales pueden enviar, etc.

Lo que haremos aquí, es crear una nueva función que va a formar un plano basado en la altura y anchura, y conectar dicha función a la señal de "pulsado" emitida por nuestro botón "Create!". Empezaremos con la importación de nuestros módulos FreeCAD, poniendo la siguiente línea al comienzo del archivo de guión, donde ya hemos mandado también la importación de QtCore y QtGui:

import FreeCAD, Part

ahora, añadamos una nueva función a nuestra clase Ui_Dialog:

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()

A continuación, tenemos que informar a Qt para que conecte el botón con la función, mediante la colocación de la siguiente línea justo antes de QtCore.QMetaObject.connectSlotsByName(Dialog):

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

Como ves, esto conecta la señal pressed() de nuestro objeto create (el Botón "Create!"), a un slot llamado createPlane, que acabamos de definir. Eso es! Ahora, como toque final, podemos añadir una pequeña función para crear el cuadro de diálogo. Así será más fácil hacer las llamadas. Fuera de la clase Ui_Dialog, vamos a añadir este código:

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!)

A continuación, en FreeCAD, sólo tenemos que hacer:

import mywidget
myDialog = mywidget.plane()

Y eso es todo amigos... Ahora puedes probar todo tipo de cosas, como por ejemplo insertar tu widget en la interfaz de FreeCAD (mira la página Pedazos de código), o la creación de herramientas personalizadas mucho más avanzado, mediante el uso de otros elementos en tu widget o complemento.

El archivo de guión completo

Este es el archivo de guión completo, como referencia:

# -*- 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("Fenetre 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

Use QFileDialog for write the file

Complete code:

# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

try:
    SaveName = QFileDialog.getSaveFileName(None,QString.fromLocal8Bit("Save a file txt"),path,             "*.txt")    # PyQt4
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
except Exception:
    SaveName, Filter = PySide.QtGui.QFileDialog.getSaveFileName(None, "Save a file txt", path,             "*.txt")   # PySide
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
if SaveName == "":                                                            # if the name file are not selected then Abord process
    App.Console.PrintMessage("Process aborted"+"\n")
else:                                                                         # if the name file are selected or created then 
    App.Console.PrintMessage("Registration of "+SaveName+"\n")                # text displayed to Report view (Menu > View > Report view checked)
    try:                                                                      # detect error ...
        file = open(SaveName, 'w')                                            # open the file selected to write (w)  # (wb is binary)
        try:                                                                  # if error detected to write ...
            # here your code
            print "here your code"
            file.write(str(1)+"\n")                                           # write the number convert in text with (str())
            file.write("FreeCAD the best")                                    # write the the text with ("  ")
        finally:                                                              # if error detected to write ... or not the file is closed
            file.close()                                                      # if error detected to write ... or not the file is closed
    except Exception:
        App.Console.PrintError("Error Registration file "+SaveName+"\n")      # detect error ... display the text in red (PrintError)

Use QFileDialog for read the file

Complete code:

# -*- coding: utf-8 -*-
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

OpenName = ""
try:
    OpenName = QFileDialog.getOpenFileName(None,QString.fromLocal8Bit("Read a file txt"),path,             "*.txt") # PyQt4
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
except Exception:
    OpenName, Filter = PySide.QtGui.QFileDialog.getOpenFileName(None, "Read a file txt", path,             "*.txt")#PySide
#                                                                     "here the text displayed on windows" "here the filter (extension)"   
if OpenName == "":                                                            # if the name file are not selected then Abord process
    App.Console.PrintMessage("Process aborted"+"\n")
else:
    App.Console.PrintMessage("Read "+OpenName+"\n")                           # text displayed to Report view (Menu > View > Report view checked)
    try:                                                                      # detect error to read file
        file = open(OpenName, "r")                                            # open the file selected to read (r)  # (rb is binary)
        try:                                                                  # detect error ...
            op = OpenName.split("/")                                          # decode the path
            op2 = op[-1].split(".")                                           # decode the file name 
            nomF = op2[0]                                                     # the file name are isolated

            App.Console.PrintMessage(str(nomF)+"\n")                          # the file name are displayed

            for ligne in file:                                                # read the file
                X  = ligne.rstrip('\n\r') #.split()                           # decode the line
                print X                                                       # print the line in report view other method 
                                                                              # (Menu > Edit > preferences... > Output window > Redirect internal Python output (and errors) to report view checked) 
        finally:                                                              # if error detected to read ... or not error the file is closed
            file.close()                                                      # if error detected to read ... or not error the file is closed
    except Exception:                                                         # if one error detected to read file
        App.Console.PrintError("Error in reading the file "+OpenName+"\n")    # if one error detected ... display the text in red (PrintError)

Use QColorDialog for get the color

Complete code:

# -*- coding: utf-8 -*-
# https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QColor.html
import PySide
from PySide import QtGui ,QtCore
from PySide.QtGui import *
from PySide.QtCore import *
path = FreeCAD.ConfigGet("UserAppData")

couleur = QtGui.QColorDialog.getColor()
if couleur.isValid():
    red   = int(str(couleur.name()[1:3]),16)    # decode hexadecimal to int()
    green = int(str(couleur.name()[3:5]),16)    # decode hexadecimal to int()
    blue  = int(str(couleur.name()[5:7]),16)    # decode hexadecimal to int()

    print couleur                               # 
    print "hexadecimal ",couleur.name()         # color format hexadecimal mode 16
    print "Red   color ",red                    # color format decimal
    print "Green color ",green                  # color format decimal
    print "Blue  color ",blue                   # color format decimal

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/es
Licence/es