1044 lines
59 KiB
HTML
1044 lines
59 KiB
HTML
<html><head><title>Dialog creation/es</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link type='text/css' href='wiki.css' rel='stylesheet'></head><body><h1>Dialog creation/es</h1></div>
|
|
|
|
<div id="mw-content-text" lang="es" dir="ltr" class="mw-content-ltr"><hr/><div class="mw-parser-output"><p>En esta página vamos a mostrar cómo crear un simple letrero de diálogo con <a rel="nofollow" class="external text" href="http://qt-project.org/doc/qt-4.8/designer-manual.html">Qt Designer</a>, 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.
|
|
</p>
|
|
<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
|
|
<ul>
|
|
<li class="toclevel-1 tocsection-1"><a href="#Dise.C3.B1ar_el_letrero_de_di.C3.A1logo"><span class="tocnumber">1</span> <span class="toctext">Diseñar el letrero de diálogo</span></a></li>
|
|
<li class="toclevel-1 tocsection-2"><a href="#Convertir_nuestro_di.C3.A1logo_a_Python"><span class="tocnumber">2</span> <span class="toctext">Convertir nuestro diálogo a Python</span></a></li>
|
|
<li class="toclevel-1 tocsection-3"><a href="#Hacer_algo_con_nuestro_di.C3.A1logo"><span class="tocnumber">3</span> <span class="toctext">Hacer algo con nuestro diálogo</span></a></li>
|
|
<li class="toclevel-1 tocsection-4"><a href="#El_archivo_de_gui.C3.B3n_completo"><span class="tocnumber">4</span> <span class="toctext">El archivo de guión completo</span></a></li>
|
|
<li class="toclevel-1 tocsection-5"><a href="#Creation_of_a_dialog_with_buttons"><span class="tocnumber">5</span> <span class="toctext">Creation of a dialog with buttons</span></a>
|
|
<ul>
|
|
<li class="toclevel-2 tocsection-6"><a href="#Method_1"><span class="tocnumber">5.1</span> <span class="toctext">Method 1</span></a></li>
|
|
<li class="toclevel-2 tocsection-7"><a href="#Method_2"><span class="tocnumber">5.2</span> <span class="toctext">Method 2</span></a></li>
|
|
</ul>
|
|
</li>
|
|
<li class="toclevel-1 tocsection-8"><a href="#Icon_personalized_in_ComboView"><span class="tocnumber">6</span> <span class="toctext">Icon personalized in ComboView</span></a></li>
|
|
<li class="toclevel-1 tocsection-9"><a href="#Use_QFileDialog_for_write_the_file"><span class="tocnumber">7</span> <span class="toctext">Use QFileDialog for write the file</span></a></li>
|
|
<li class="toclevel-1 tocsection-10"><a href="#Use_QFileDialog_for_read_the_file"><span class="tocnumber">8</span> <span class="toctext">Use QFileDialog for read the file</span></a></li>
|
|
<li class="toclevel-1 tocsection-11"><a href="#Use_QColorDialog_for_get_the_color"><span class="tocnumber">9</span> <span class="toctext">Use QColorDialog for get the color</span></a></li>
|
|
<li class="toclevel-1 tocsection-12"><a href="#Some_useful_commands"><span class="tocnumber">10</span> <span class="toctext">Some useful commands</span></a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<h2><span class="mw-headline" id="Dise.C3.B1ar_el_letrero_de_di.C3.A1logo">Diseñar el letrero de diálogo</span></h2>
|
|
<p>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.
|
|
</p><p>Hay un par de conceptos que debes saber a la hora de diseñar la interfaz:
|
|
</p>
|
|
<ul><li> <a rel="nofollow" class="external text" href="http://en.wikipedia.org/wiki/Modal_window">Letreros de diálogo Modales/no modales</a>: 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.</li>
|
|
<li> 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.</li>
|
|
<li> 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.</li></ul>
|
|
<p>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:
|
|
</p><p><a href="https://www.freecadweb.org/wiki/index.php?title=File:Qttestdialog.jpg" class="image"><img alt="Qttestdialog.jpg" src="Qttestdialog.jpg" width="210" height="216" /></a>
|
|
</p><p>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:
|
|
</p><p><a href="https://www.freecadweb.org/wiki/index.php?title=File:Qtdesigner-screenshot.jpg" class="image"><img alt="Qtdesigner-screenshot.jpg" src="Qtdesigner-screenshot.jpg" width="800" height="486" /></a>
|
|
</p><p>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 <b>3 etiquetas</b>, 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.
|
|
</p><p>A continuación, agrega <b>2 LineEdits</b>, 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 <b>PushButton</b>, que es el botón que el usuario deberá pulsar después de llenar los 2 campos.
|
|
</p><p>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.
|
|
</p><p>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:
|
|
</p><p><a href="https://www.freecadweb.org/wiki/index.php?title=File:Qtpropeditor.jpg" class="image"><img alt="Qtpropeditor.jpg" src="Qtpropeditor.jpg" width="348" height="321" /></a>
|
|
</p>
|
|
<h2><span class="mw-headline" id="Convertir_nuestro_di.C3.A1logo_a_Python">Convertir nuestro diálogo a Python</span></h2>
|
|
<p>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:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>pyuic mywidget.ui > mywidget.py</pre></div>
|
|
<p>Into Windows pyuic.py are located in "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py"
|
|
For create batch file "compQt4.bat:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>@"C:\Python27\python" "C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" -x %1.ui > %1.py</pre></div>
|
|
<p>In the console Dos type without extension
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>compQt4 myUiFile</pre></div>
|
|
<p>Into Linux : to do
|
|
</p><p>Since FreeCAD progressively moved away from PyQt after version 0.13, in favour of <a rel="nofollow" class="external text" href="http://qt-project.org/wiki/PySide">PySide</a> (Choice your PySide install <a rel="nofollow" class="external text" href="http://pyside.readthedocs.org/en/latest/building/">building PySide</a>), to make the file based on PySide now you have to use:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>pyside-uic mywidget.ui -o mywidget.py</pre></div>
|
|
<p>Into Windows uic.py are located in "C:\Python27\Lib\site-packages\PySide\scripts\uic.py"
|
|
For create batch file "compSide.bat":
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>@"C:\Python27\python" "C:\Python27\Lib\site-packages\PySide\scripts\uic.py" %1.ui > %1.py</pre></div>
|
|
<p>In the console Dos type without extension
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>compSide myUiFile</pre></div>
|
|
<p>Into Linux : to do
|
|
</p><p><br />
|
|
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:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>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))
|
|
...</pre></div>
|
|
<p>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).
|
|
</p><p>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:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>from PySide import QtGui
|
|
import mywidget
|
|
d = QtGui.QWidget()
|
|
d.ui = mywidget.Ui_Dialog()
|
|
d.ui.setupUi(d)
|
|
d.show()</pre></div>
|
|
<p>¡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:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>d.hide()</pre></div>
|
|
<h2><span class="mw-headline" id="Hacer_algo_con_nuestro_di.C3.A1logo">Hacer algo con nuestro diálogo</span></h2>
|
|
<p>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 <a rel="nofollow" class="external text" href="http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/classes.html">Documentación de referencia de PyQt</a> enumera todos los widgets Qt, lo que pueden hacer, que señales pueden enviar, etc.
|
|
</p><p>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:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>import FreeCAD, Part</pre></div>
|
|
<p>ahora, añadamos una nueva función a nuestra clase Ui_Dialog:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>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()</pre></div>
|
|
<p>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):
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>QtCore.QObject.connect(self.create,QtCore.SIGNAL("pressed()"),self.createPlane)</pre></div>
|
|
<p>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:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>class plane():
|
|
def __init__(self):
|
|
self.d = QtGui.QWidget()
|
|
self.ui = Ui_Dialog()
|
|
self.ui.setupUi(self.d)
|
|
self.d.show()</pre></div>
|
|
<p>(Python reminder: the __init__ method of a class is automatically executed whenever a new object is created!)
|
|
</p><p>A continuación, en FreeCAD, sólo tenemos que hacer:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>import mywidget
|
|
myDialog = mywidget.plane()</pre></div>
|
|
<p>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 <a href="https://www.freecadweb.org/wiki/index.php?title=Code_snippets/es" title="Code snippets/es">Pedazos de código</a>), o la creación de herramientas personalizadas mucho más avanzado, mediante el uso de otros elementos en tu widget o complemento.
|
|
</p>
|
|
<h2><span class="mw-headline" id="El_archivo_de_gui.C3.B3n_completo">El archivo de guión completo</span></h2>
|
|
<p>Este es el archivo de guión completo, como referencia:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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()</pre></div>
|
|
<h2><span class="mw-headline" id="Creation_of_a_dialog_with_buttons">Creation of a dialog with buttons</span></h2>
|
|
<h3><span class="mw-headline" id="Method_1">Method 1</span></h3>
|
|
<p>An example of a dialog box complete with its connections.
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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()</pre></div>
|
|
<p>Here the same window but with an icon on each button.
|
|
</p><p>Download associated icons (Click rigth "Copy the image below ...)"
|
|
</p><p><a href="https://www.freecadweb.org/wiki/index.php?title=File:Icone01.png" class="image"><img alt="Icone01.png" src="Icone01.png" width="64" height="64" /></a> <a href="https://www.freecadweb.org/wiki/index.php?title=File:Icone02.png" class="image"><img alt="Icone02.png" src="Icone02.png" width="64" height="64" /></a> <a href="https://www.freecadweb.org/wiki/index.php?title=File:Icone03.png" class="image"><img alt="Icone03.png" src="Icone03.png" width="64" height="64" /></a>
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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()</pre></div>
|
|
<p>Here the code to display the icon on the <b>pushButton</b>, change the name for another button, (<b>radioButton, checkBox</b>) and the path to the icon.
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre> # 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</pre></div>
|
|
<p>The command
|
|
<b>UserAppData</b> gives the user path
|
|
<b>AppHomePath</b> gives the installation path of FreeCAD
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># path = FreeCAD.ConfigGet("UserAppData")
|
|
path = FreeCAD.ConfigGet("AppHomePath")</pre></div>
|
|
<p>This command reverses the horizontal button, right to left.
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>self.pushButton.setLayoutDirection(QtCore.Qt.RightToLeft) # This command reverses the direction of the button</pre></div>
|
|
<h3><span class="mw-headline" id="Method_2">Method 2</span></h3>
|
|
<p>Another method to display a window, here by creating a file <b>QtForm.py</b> which contains the header program (module called with <b>import QtForm</b>), and a second module that contains the code window all these accessories, and your code (the calling module).
|
|
</p><p>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.
|
|
</p><p>The file <b>QtForm.py</b>
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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))</pre></div>
|
|
<p>The appellant, file that contains the window and your code.
|
|
</p><p>The file my_file.py
|
|
</p><p>The connections are to do, a good exercise.
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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()</pre></div>
|
|
<p><b>Other example</b>
|
|
</p>
|
|
<center>
|
|
<ul class="gallery mw-gallery-traditional">
|
|
<li class="gallerybox" style="width: 435px"><div style="width: 435px">
|
|
<div class="thumb" style="width: 430px;"><div style="margin:15px auto;"><a href="https://www.freecadweb.org/wiki/index.php?title=File:Qt_Example_00.png" class="image"><img alt="" src="167px-Qt_Example_00.png" width="167" height="200" srcset="/wiki/images/thumb/f/fe/Qt_Example_00.png/250px-Qt_Example_00.png 1.5x, /wiki/images/thumb/f/fe/Qt_Example_00.png/333px-Qt_Example_00.png 2x" /></a></div></div>
|
|
<div class="gallerytext">
|
|
<p>Qt example 1
|
|
</p>
|
|
</div>
|
|
</div></li>
|
|
<li class="gallerybox" style="width: 435px"><div style="width: 435px">
|
|
<div class="thumb" style="width: 430px;"><div style="margin:15px auto;"><a href="https://www.freecadweb.org/wiki/index.php?title=File:Qt_Example_01.png" class="image"><img alt="" src="167px-Qt_Example_01.png" width="167" height="200" srcset="/wiki/images/thumb/d/d4/Qt_Example_01.png/250px-Qt_Example_01.png 1.5x, /wiki/images/thumb/d/d4/Qt_Example_01.png/333px-Qt_Example_01.png 2x" /></a></div></div>
|
|
<div class="gallerytext">
|
|
<p>Qt example details
|
|
</p>
|
|
</div>
|
|
</div></li>
|
|
</ul>
|
|
</center>
|
|
<div style="clear:both"></div>
|
|
<p><br />
|
|
Are treated :
|
|
</p>
|
|
<ol><li> icon for window</li>
|
|
<li> horizontalSlider</li>
|
|
<li> progressBar horizontal</li>
|
|
<li> verticalSlider</li>
|
|
<li> progressBar vertical</li>
|
|
<li> lineEdit</li>
|
|
<li> lineEdit</li>
|
|
<li> doubleSpinBox</li>
|
|
<li> doubleSpinBox</li>
|
|
<li> doubleSpinBox</li>
|
|
<li> buttom</li>
|
|
<li> buttom</li>
|
|
<li> radioButtom with icons</li>
|
|
<li> checkBox with icon checked and unchecked</li>
|
|
<li> textEdit</li>
|
|
<li> graphicsView with 2 graphes</li></ol>
|
|
<p>The code page and the icons <a href="Qt_Example.html" title="Qt Example">Qt_Example</a>
|
|
</p>
|
|
<h2><span class="mw-headline" id="Icon_personalized_in_ComboView">Icon personalized in ComboView</span></h2>
|
|
<p>Here example create object with property and icon personalized in ComboView
|
|
</p><p>Download the example icon to place in same directory of the macro <a href="https://www.freecadweb.org/wiki/index.php?title=File:FreeCADIco.png" class="image" title="icon Example for the macro"><img alt="icon Example for the macro" src="24px-FreeCADIco.png" width="24" height="22" srcset="/wiki/images/thumb/8/86/FreeCADIco.png/36px-FreeCADIco.png 1.5x, /wiki/images/thumb/8/86/FreeCADIco.png/48px-FreeCADIco.png 2x" /></a>
|
|
</p><p>The icon used is one icon to file disk, one icon to resource FreeCAD and one icon include in the macro (format .XPM)
|
|
</p><p><a href="https://www.freecadweb.org/wiki/index.php?title=File:Qt_Example_02.png" class="image" title="icon personalized"><img alt="icon personalized" src="Qt_Example_02.png" width="338" height="490" /></a>
|
|
</p>
|
|
<div style="clear:both"></div>
|
|
<p><br />
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>import PySide
|
|
import FreeCAD, FreeCADGui, Part
|
|
from pivy import coin
|
|
from PySide import QtGui ,QtCore
|
|
from PySide.QtGui import *
|
|
from PySide.QtCore import *
|
|
import Draft
|
|
|
|
global path
|
|
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path in FreeCAD preferences
|
|
path = param.GetString("MacroPath","") + "/" # macro path
|
|
path = path.replace("\\","/") # convert the "\" to "/"
|
|
|
|
|
|
class IconViewProviderToFile: # Class ViewProvider create Property view of object
|
|
def __init__( self, obj, icon):
|
|
self.icone = icon
|
|
|
|
def getIcon(self): # GetIcon
|
|
return self.icone
|
|
|
|
def attach(self, obj): # Property view of object
|
|
self.modes = []
|
|
self.modes.append("Flat Lines")
|
|
self.modes.append("Shaded")
|
|
self.modes.append("Wireframe")
|
|
self.modes.append("Points")
|
|
obj.addDisplayMode( coin.SoGroup(),"Flat Lines" ) # Display Mode
|
|
obj.addDisplayMode( coin.SoGroup(),"Shaded" )
|
|
obj.addDisplayMode( coin.SoGroup(),"Wireframe" )
|
|
obj.addDisplayMode( coin.SoGroup(),"Points" )
|
|
return self.modes
|
|
|
|
def getDisplayModes(self,obj):
|
|
return self.modes
|
|
|
|
#####################################################
|
|
########## Example with icon to file # begin ########
|
|
#####################################################
|
|
|
|
object1 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_In_File_Disk") # create your object
|
|
object1.addProperty("App::PropertyString","Identity", "ExampleTitle0", "Identity of object").Identity = "FCSpring" # Identity of object
|
|
object1.addProperty("App::PropertyFloat" ,"Pitch", "ExampleTitle0", "Pitch betwen 2 heads").Pitch = 2.0 # other Property Data
|
|
object1.addProperty("App::PropertyBool" ,"View", "ExampleTitle1", "Hello world").View = True # ...
|
|
object1.addProperty("App::PropertyColor" ,"LineColor","ExampleTitle2", "Color to choice").LineColor = (0.13,0.15,0.37) # ...
|
|
#...other Property Data
|
|
#...other Property Data
|
|
#
|
|
object1.ViewObject.Proxy = IconViewProviderToFile( object1, path + "FreeCADIco.png") # icon download to file
|
|
App.ActiveDocument.recompute()
|
|
#
|
|
#__Detail__:
|
|
# FreeCAD.ActiveDocument.addObject( = create now object personalized
|
|
# "App::FeaturePython", = object as FeaturePython
|
|
# "Icon_In_File_Disk") = internal name of your object
|
|
#
|
|
#
|
|
# "App::PropertyString", = type of Property , availlable : PropertyString, PropertyFloat, PropertyBool, PropertyColor
|
|
# "Identity", = name of the feature
|
|
# "ExampleTitle0", = title of the "section"
|
|
# "Identity of object") = tooltip displayed on mouse
|
|
# .Identity = variable (same of name of the feature)
|
|
# object1.ViewObject.Proxy = create the view object and gives the icon
|
|
#
|
|
########## example with icon to file end
|
|
|
|
|
|
|
|
#####################################################
|
|
########## Example with icon in macro # begin #######
|
|
#####################################################
|
|
|
|
def setIconInMacro(self): # def contener the icon in format .xpm
|
|
# File format XPM created by Gimp "https://www.gimp.org/"
|
|
# Choice palette Tango
|
|
# Create your masterwork ...
|
|
# For export the image in XPM format
|
|
# Menu File > Export as > .xpm
|
|
# (For convert image true color in Tango color palette :
|
|
# Menu Image > Mode > Indexed ... > Use custom palette > Tango Icon Theme > Convert)
|
|
return """
|
|
/* XPM */
|
|
static char * XPM[] = {
|
|
"22 24 5 1",
|
|
" c None",
|
|
".c #CE5C00",
|
|
"+c #EDD400",
|
|
"@c #F57900",
|
|
"#c #8F5902",
|
|
" ",
|
|
" ",
|
|
" .... ",
|
|
" ..@@@@.. ",
|
|
" . ...@...... ",
|
|
" .+++++++++... ",
|
|
" . ....++... ",
|
|
" .@..@@@@@@.+++++.. ",
|
|
" .@@@@@..# ++++ .. ",
|
|
" . ++++ .@.. ",
|
|
" .++++++++ .@@@.+. ",
|
|
" . ..@@@@@. ++. ",
|
|
" ..@@@@@@@@@. +++ . ",
|
|
" ....@...# +++++ @.. ",
|
|
" . ++++++++ .@. . ",
|
|
" .++++++++ .@@@@ . ",
|
|
" . #....@@@@. ++. ",
|
|
" .@@@@@@@@@.. +++ . ",
|
|
" ........ +++++... ",
|
|
" ... ..+++++ ..@.. ",
|
|
" ...... .@@@ +. ",
|
|
" ......++. ",
|
|
" ... ",
|
|
" "};
|
|
"""
|
|
|
|
object2 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_XPM_In_Macro") #
|
|
object2.addProperty("App::PropertyString","Identity","ExampleTitle","Identity of object").Identity = "FCSpring"
|
|
#...other Property Data
|
|
#...other Property Data
|
|
#
|
|
object2.ViewObject.Proxy = IconViewProviderToFile( object2, setIconInMacro("")) # icon in macro (.XPM)
|
|
App.ActiveDocument.recompute()
|
|
########## example with icon in macro end
|
|
|
|
|
|
|
|
####################################################################
|
|
########## Example with icon to FreeCAD ressource # begin ##########
|
|
####################################################################
|
|
|
|
object3 = FreeCAD.ActiveDocument.addObject("App::FeaturePython", "Icon_Ressource_FreeCAD") #
|
|
object3.addProperty("App::PropertyString","Identity","ExampleTitle","Identity of object").Identity = "FCSpring"
|
|
#...other Property Data
|
|
#...other Property Data
|
|
#
|
|
object3.ViewObject.Proxy = IconViewProviderToFile( object3, ":/icons/Draft_Draft.svg") # icon to FreeCAD ressource
|
|
App.ActiveDocument.recompute()
|
|
########## example with icon to FreeCAD ressource end</pre></div>
|
|
<p>Other complete example creation cube with icon in macro
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>#https://forum.freecadweb.org/viewtopic.php?t=10255#p83319
|
|
import FreeCAD, Part, math
|
|
from FreeCAD import Base
|
|
from PySide import QtGui
|
|
|
|
global path
|
|
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Macro")# macro path in FreeCAD preferences
|
|
path = param.GetString("MacroPath","") + "/" # macro path
|
|
path = path.replace("\\","/") # convert the "\" to "/"
|
|
|
|
def setIconInMacro(self):
|
|
return """
|
|
/* XPM */
|
|
static char * xpm[] = {
|
|
"22 22 12 1",
|
|
" c None",
|
|
".c #A40000",
|
|
"+c #2E3436",
|
|
"@c #CE5C00",
|
|
"#c #F57900",
|
|
"$c #FCAF3E",
|
|
"%c #5C3566",
|
|
"&c #204A87",
|
|
"*c #555753",
|
|
"=c #3465A4",
|
|
"-c #4E9A06",
|
|
";c #729FCF",
|
|
" ",
|
|
" ",
|
|
" ",
|
|
" .. .. ",
|
|
" +@#+++.$$ ",
|
|
" +.#+%..$$ ",
|
|
" &*$ &*#* ",
|
|
" & =&= = ",
|
|
" ++& +.== %= ",
|
|
" ++$@ ..$ %= & ",
|
|
" ..-&%.#$$ &## +=$ ",
|
|
" .# ..$ ..#%%.#$$ ",
|
|
" ; =+=## %-$# ",
|
|
" &= ;& %= ",
|
|
" ;+ &=; %= ",
|
|
" ++$- +*$- ",
|
|
" .#&&+.@$$ ",
|
|
" ..$# ..$# ",
|
|
" .. .. ",
|
|
" ",
|
|
" ",
|
|
" "};
|
|
"""
|
|
|
|
class PartFeature:
|
|
def __init__(self, obj):
|
|
obj.Proxy = self
|
|
|
|
class Box(PartFeature):
|
|
def __init__(self, obj):
|
|
PartFeature.__init__(self, obj)
|
|
obj.addProperty("App::PropertyLength", "Length", "Box", "Length of the box").Length = 1.0
|
|
obj.addProperty("App::PropertyLength", "Width", "Box", "Width of the box" ).Width = 1.0
|
|
obj.addProperty("App::PropertyLength", "Height", "Box", "Height of the box").Height = 1.0
|
|
|
|
def onChanged(self, fp, prop):
|
|
try:
|
|
if prop == "Length" or prop == "Width" or prop == "Height":
|
|
fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)
|
|
except:
|
|
pass
|
|
|
|
def execute(self, fp):
|
|
fp.Shape = Part.makeBox(fp.Length,fp.Width,fp.Height)
|
|
|
|
class ViewProviderBox:
|
|
def __init__(self, obj, icon):
|
|
obj.Proxy = self
|
|
self.icone = icon
|
|
|
|
def getIcon(self):
|
|
return self.icone
|
|
|
|
def attach(self, obj):
|
|
return
|
|
|
|
def setupContextMenu(self, obj, menu):
|
|
action = menu.addAction("Set default height")
|
|
action.triggered.connect(lambda f=self.setDefaultHeight, arg=obj:f(arg))
|
|
|
|
action = menu.addAction("Hello World")
|
|
action.triggered.connect(self.showHelloWorld)
|
|
|
|
def setDefaultHeight(self, view):
|
|
view.Object.Height = 15.0
|
|
|
|
def showHelloWorld(self):
|
|
QtGui.QMessageBox.information(None, "Hi there", "Hello World")
|
|
|
|
def makeBox():
|
|
FreeCAD.newDocument()
|
|
a=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Box")
|
|
Box(a)
|
|
# ViewProviderBox(a.ViewObject, path + "FreeCADIco.png") # icon download to file
|
|
# ViewProviderBox(a.ViewObject, ":/icons/Draft_Draft.svg") # icon to FreeCAD ressource
|
|
ViewProviderBox(a.ViewObject, setIconInMacro("")) # icon in macro (.XPM)
|
|
App.ActiveDocument.recompute()
|
|
|
|
makeBox()</pre></div>
|
|
<h2><span class="mw-headline" id="Use_QFileDialog_for_write_the_file">Use QFileDialog for write the file</span></h2>
|
|
<p>Complete code:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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)
|
|
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 (" ")
|
|
except Exception: # if error detected to write
|
|
App.Console.PrintError("Error write file "+"\n") # detect error ... display the text in red (PrintError)
|
|
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 Open file "+SaveName+"\n") # detect error ... display the text in red (PrintError)</pre></div>
|
|
<h2><span class="mw-headline" id="Use_QFileDialog_for_read_the_file">Use QFileDialog for read the file</span></h2>
|
|
<p>Complete code:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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 ...
|
|
# here your code
|
|
print "here your code"
|
|
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)
|
|
except Exception: # if error detected to read
|
|
App.Console.PrintError("Error read file "+"\n") # detect error ... display the text in red (PrintError)
|
|
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 Open the file "+OpenName+"\n") # if one error detected ... display the text in red (PrintError)</pre></div>
|
|
<h2><span class="mw-headline" id="Use_QColorDialog_for_get_the_color">Use QColorDialog for get the color</span></h2>
|
|
<p>Complete code:
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># -*- 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</pre></div>
|
|
<h2><span class="mw-headline" id="Some_useful_commands">Some useful commands</span></h2>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># 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))</pre></div>
|
|
<p>By using the characters with accents, where you get the error :
|
|
</p><p>Several solutions are possible.
|
|
</p><p><font color="#FF0000"><b>UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-2: invalid data</b></font>
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># 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')</pre></div>
|
|
<p>or with the procedure
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>def utf8(unio):
|
|
return unicode(unio).encode('UTF8')</pre></div>
|
|
<p><font color="#FF0000"><b>UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 9: ordinal not in range(128)</b></font>
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre># conversion
|
|
a = u"Nom de l'élément : "
|
|
f.write('''a.encode('iso-8859-1')'''+str(element_)+"\n")</pre></div>
|
|
<p>or with the procedure
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>def iso8859(encoder):
|
|
return unicode(encoder).encode('iso-8859-1')</pre></div>
|
|
<p>or
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>iso8859(unichr(176))</pre></div>
|
|
<p>or
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>unichr(ord(176))</pre></div>
|
|
<p>or
|
|
</p>
|
|
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>uniteSs = "mm"+iso8859(unichr(178))
|
|
print unicode(uniteSs, 'iso8859')</pre></div>
|
|
<p><br />
|
|
</p>
|
|
|
|
<div style="clear:both"></div>
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div><div class="printfooter">
|
|
Online version: "<a dir="ltr" href="https://www.freecadweb.org/wiki/index.php?title=Dialog_creation/es&oldid=245356">http://www.freecadweb.org/wiki/index.php?title=Dialog_creation/es&oldid=245356</a>"</div>
|
|
<div id="catlinks" class="catlinks" data-mw="interface"></div><div class="visualClear"></div>
|
|
</div>
|
|
</div>
|
|
<div id="mw-navigation">
|
|
<h2>Navigation menu</h2>
|
|
|
|
</body></html> |