Dialog creation/de

Auf dieser Seite zeigen wir, wie man einen einfachen Qt-Dialog aufbaut mit Qt-Designer, dem offiziellen Werkzeug von Qt, um Schnittstellen zu entwerfen. Das Ergebnis wandeln wir dann um in Python-Code und verwenden es anschließend innerhalb von FreeCAD. Ich werde in diesem Beispiel davon ausgehen, dass Sie bereits wissen, wie man Python-Skripte bearbeitet und ausführt und dass Sie einfache Dinge in einem Terminal-Fenster wie navigieren, etc. ebenfalls können. Ebenso muss natürlich auch pyqt installiert sein.

Das Entwerfen des Dialogs
In CAD-Anwendungen ist es sehr wichtig, eine gute UI (Benutzerschnittstelle) zu entwerfend. Beinahe alles, das der Benutzer tun wird, wird über ein Teil der Schnittstelle passieren: das Lesen von Dialog-Kästen, drücken von Knöpfen, die Auswahl zwischen Piktogrammen, usw. So ist es sehr wichtig, genau darüber nachzudenken, was Sie tun wollen, wie Sie wollen, dass sich der Benutzer verhält und wie der Arbeitsablauf Ihrer Handlung sein wird.

Ein paar Konzepte sollte man bei der Gestaltung der Schnittstelle kennen:
 * Dialoge: Ein modaler Dialog erscheint auf Ihrem Schirm, unterbricht die Handlung des Hauptfensters, zwingt den Benutzer auf den Dialog zu antworten, während ein nichtmodaler Dialog Sie nicht hindert, am Hauptfenster weiter zu arbeiten. In einigen Fällen ist der erste besser, in anderen Fällen nicht.
 * Erkennen, was erforderlich ist und was optional: Stellen Sie sicher, dass der Benutzer weiß, was er tun muss. Etikettieren Sie alles mit der richtigen Beschreibung, verwenden Sie tooltips usw.
 * Die Trennung von Befehlen und Parametern: Das wird gewöhnlich mit Knöpfen und Texteingabefeldern getan. Der Benutzer weiß, dass das Klicken eines Knopfs eine Handlung erzeugen wird, indem er einen Wert innerhalb eines Textfeldes ändert, wird irgendwo ein Parameter geändert. Heutzutage aber wissen Benutzer gewöhnlich gut, was ein Knopf ist, was ein Eingangsfeld usw ist. Das Schnittstellen-Werkzeug Qt, das wir verwenden, ist eines der modernsten Werkzeuge und wir werden uns nicht viel darum sorgen müssen, Dinge verständlich zu machen, da sie bereits in sich selbst sehr klar sein werden.

Nachdem wir gut definiert haben, was wir tun werden, ist es Zeit, den Qt-Designer zu öffnen. Lassen Sie uns einen sehr einfachen Dialog entwerfen:



Wir werden dann mit diesem Dialog in FreeCAD eine schöne rechteckige Ebene erzeugen. Vielleicht finden Sie es nicht sehr nützlich, nette rechteckige Fläche zu produzieren, aber es wird leicht sein, sie später zu ändern, um komplexere Dinge zu tun. Wenn Sie es öffnen, sieht Qt-Designer wie folgt aus:



Die Bedienung ist recht einfach. Auf der linken Leiste haben Sie Elemente, die Sie auf Ihr Widget ziehen können. Rechts haben Sie Eigenschaften-Tafeln, die alle Arten von änderbaren Eigenschaften von ausgewählten Elementen zeigen. Beginnen Sie mit dem Erstellen eines neuen Widgets. Wählen Sie "Dialog ohne Knöpfe", da wir nicht die Standard-OK/Abbrechen Knöpfe wollen. Jetzt ziehen auf Ihr Widget 3 Label, eins für den Titel, eins mit Namen "Höhe" und eins mit Namen "Breite". Label sind einfache Texte, die auf Ihrem Widget angezeigt werden, nur um den Benutzer zu informieren. Wenn Sie ein Label auswählen, werden auf der rechten Seite mehrere Eigenschaften erscheinen, die Sie nach Bedarf ändern können, wie Schriftart, Größe, usw.

Dann fügen Sie 2 LineEdits ein, dies sind Textfelder, die der Benutzer ausfüllen kann, eins für die Höhe und eins für die Breite. Auch hier können wir Eigenschaften bearbeiten. Warum nicht, zum Beispiel, einen Standardwert vorgeben? Zum Beispiel 1,00 für jeden. Auf diese Weise werden beide Werte bereits ausgefüllt sein, wenn der Benutzer den Dialog sieht, und wenn es so stimmt, kann er den Knopf direkt drücken und spart wertvolle Zeit. Dann fügen Sie einen PushButton hinzu, das ist die Schaltfläche, die der Benutzer drücken muss, nachdem er die zwei Felder füllte.

Beachten Sie, dass ich sehr einfache Steuerungen gewählt habe, aber Qt noch viele andere Optionen hat, zum Beispiel könnten Sie Spinboxes statt LineEdits usw. verwenden.. Werfen Sie doch einen Blick darauf, was verfügbar ist, vielleicht kommen Ihnen dabei noch weitere Ideen.

Das ist soweit alles, was wir im Qt-Designer tun müssen. Eine letzte Sache, wir sollten alle unsere Elemente mit einfacheren Namen bezeichnen, so dass es leichter wird, sie in unseren Skripten zu identifizieren:



Umwandeln unseres Dialogs zu Python
Jetzt werden wir unser Widget irgendwo speichern. Er wird als .ui-Datei gespeichert, die wir einfach mittels pyuic zu einem Python-Skript wandeln werden. Unter Windows ist das pyuic-Programm meistens mit pyqt gebündelt (zu überprüfen), auf Linux werden Sie es wahrscheinlich extra mit Ihrem Paketmanager installieren müssen (auf Debian-beruhenden Systemen, ist es ein Teil des pyqt4-dev-tools Pakets). Für die Konvertierung müssen Sie ein Terminal-Fenster (oder ein Fenster der Eingabeaufforderung unter Windows) öffnen, in welchem Sie zu Ihrer .ui-Datei navigieren und dort dann folgendes eingeben: Unter Windows ist pyuic.py in "C:\Python27\Lib\site-packages\PyQt4\uic\"zu finden. Zu Konvertierung legen wir die Batch-Datei "compQt4.bat" an: In der DOS-Konsole tippen Sie (ohne Dateierweiterung): Unter Linux: to do

Nachdem sich FreeCAD nach v0.13 zunehmend von PyQt zugunsten von PySide entfernt hat (wählen Sie Ihre building PySide-Installation), müssen Sie zur Erstellung der Datei basierend auf PySide folgendes angeben:

Unter Windows ist uic.py in "C:\Python27\Lib\site-packages\PySide\scripts\" zu finden. Erstellen Sie eine Batch-Datei namens "compSide.bat": In der DOS-Konsole tippen Sie (ohne Dateierweiterung): Unter Linux: to do

Auf einigen Systemen wird das Programm pyuic4 statt pyuic heißen. Das wird die .ui-Datei in ein Python-Skript umwandeln. Wenn wir die mywidget.py-Datei öffnen, ist der Inhalt sehr leicht zu verstehen: Wie Sie sehen, hat es eine sehr einfache Struktur: eine Klasse genannt Ui_Dialog wird erstellt, die die Elemente der Benutzeroberfläche unseres Widgets speichert. Diese Klasse hat zwei Methoden, eine für die Einrichtung des Widgets und eine für die Übersetzung ihres Inhalts, das ist ein Teil des allgemeinen Qt-Mechanismus für die Übersetzung von Interface-Elementen. Das Setup-Verfahren erzeugt einfach eins nach dem anderen die Widgets, wie wir sie in Qt-Designer definiert haben und setzt ihre Optionen, die wir ebenfalls gewählt haben. Dann wird die ganze Schnittstelle schließlich übersetzt, die SLOTS werden verbunden (wir werden darüber später sprechen).

Wir können jetzt ein neues Widget erstellen und diese Klasse verwenden, um seine Schnittstelle zu schaffen. Wir können bereits unser Widget in Aktion sehen, indem wir unsere mywidget.py Datei an einem Ort speichern, wo FreeCAD es findet (im FreeCAD bin-Verzeichnis, oder in einem der Mod-Unterverzeichnisse), und dann im FreeCAD Python-Interpreter eintippen: Und unser Dialog wird erscheinen! Beachten Sie, dass unser Python-Interpreter immer noch arbeitet, wir haben einen nichtmodalen Dialog. Um es zu abzuschließen, können wir (abgesehen von einem Klick auf das Schließen-Symbol, natürlich) eingeben:

Lassen wir unseren Dialog etwas tun
Wo wir jetzt unseren Dialog schon anzeigen und ausblenden können, gibt es nur eines zu tun: Es muss auch etwas ausführen! Wenn Sie ein bisschen mit dem Qt-Designer spielen, entdecken Sie schnell eine ganze Abteilung genannt "Signale und Slots". Grundsätzlich funktioniert es so: Elemente auf Ihren Widgets (in Qt-Terminologie, diese Elemente sind selbst Widgets) können Signale senden. Diese Signale unterscheiden sich je nach Widget-Typ. Zum Beispiel kann eine Taste ein Signal senden, wenn sie gedrückt wird und wenn sie losgelassen wird. Diese Signale können mit Slots verbunden werden, die spezielle Funktionen von anderen Widgets (z. B. einen Dialog, einen "close"-Slot, auf den Sie das Signal von einem Schließen-Button verbinden) oder benutzerdefinierte Funktionen sein können. Die Seite PyQt Reference Documentation listet alle Qt-Widgets, was sie tun können, welche Signale sie senden können, etc.

Was wir hier tun werden, ist eine neue Funktion zu erstellen, die eine Ebene erzeugt, beruhend auf Höhe und Breite, und in Verbindung steht diese Funktion mit dem "gedrückt"-Signal, das unser "Create"-Knopf abgibt. Also wollen wir mit dem Importieren unserer FreeCAD Module beginnen, indem Sie die folgende Zeile am Anfang des Skripts, wo wir bereits QtCore und QtGui importieren, einfügen: Jetzt werden wir eine neue Funktion in unsere Ui_Dialog-Klasse einfügen: Nun müssen wir Qt klarmachen, dass der Knopf mit der Funktion verbunden werden muss. Dazu geben wir die folgende Zeile ein, aber VOR der Zeile QtCore.QMetaObject.connectSlotsByName(Dialog): Dies, wie Sie sehen, verbindet das pressed-Signal unseres create-Objekts (den "Create!" button), zu einem Slot mit Namen createPlane, den wir gerade definiert haben. Das ist alles! Jetzt, als eine Feinschliff, können wir eine kleine Funktion hinzufügen, um den Dialog zu erzeugen, dadurch wird der Aufruf erleichtert. Außerhalb der Ui_Dialog Klasse, wollen wir diesen Code hinzufügen: (Python-Erinnerung: Die __init__-Methode einer Klasse wird automatisch ausgeführt, wenn ein neues Objekt erzeugt wird!)

Dann brauchen wir in FreeCAD (Pythonkonsole) nur noch folgendes zu tun: Das ist alles, Leute ... Jetzt können Sie alle möglichen Dinge versuchen, wie zum Beispiel das Einfügen Ihres Widgets in die FreeCAD-Oberfläche (siehe Code snippets/de-Seite) oder erstellen Sie weitere, fortgeschrittene benutzerdefinierte Tools, durch die Verwendung anderer Elemente auf Ihrem Widget.

Das komplette Script
Dies ist das komplette Script, nur als Referenz:

Methode 1
Ein Beispiel einer Dialog-Box komplett mit Verbindungen. Hier das gleiche Fenster, aber mit einem Piktogramm (icon) auf jedem Knopf.

Laden Sie die verbundenen Piktogramme herunter (rechtsklick auf "Copy the image below...")



Hier der Code, um das Piktogramm auf dem pushButton anzuzeigen, den Namen eines anderen Knopfes zu ändern (radioButton, checkBox) und den Pfad des Piktogramms. Der Befehl UserAppData liefert den Benutzer-Pfad, AppHomePath den Installationspfad von FreeCAD This command reverses the horizontal button, right to left.

Methode 2
Eine weitere Methode zur Anzeige eines Fensters, hier durch Erstellung einer Datei QtForm.py, die das Header-Programm enthält (ein Modul aufgerufen mit import QtForm) und ein zweites Modul, das das Code-Fenster all dieser Zusatzteile enthält und Ihren Code (das aufrufende Modul).

Diese Methode erfordert zwei separate Dateien, erlaubt aber die Verkürzung Ihres Programms durch den Import der Datei QtForm.py. Dann verteilen Sie diese beiden Dateien zusammen, denn sie sind "untrennbar".

Die Datei QtForm.py Die aufrufende Datei, die das Fenster und Ihren Code enthält.

Die Datei my_file.py

Die Verbindungen fehlen noch, eine gute Übung.

Weiteres Beispiel

Are treated :

Die Code-Seite und die Piktogramme Qt_Beispiel
 * 1) Piktogramm für Fenster
 * 2) horizontaler Schieber (horizontalSlider)
 * 3) Fortschrittbalken, horizontal (progressBar horizontal)
 * 4) vertikaler Schieber (verticalSlider)
 * 5) Fortschrittbalken, vertikal (progressBar vertical)
 * 6) lineEdit
 * 7) lineEdit
 * 8) doubleSpinBox
 * 9) doubleSpinBox
 * 10) doubleSpinBox
 * 11) Knopf (button)
 * 12) Knopf (button)
 * 13) Radio-Knopf mit Piktogrammen (radioButton with icons)
 * 14) Ankreuzfeld mit Piktogramm [aktiviert/deaktiviert] (checkBox with icon checked and unchecked)
 * 15) textEdit
 * 16) Grafikansicht mit zwei Graphen (graphicsView with 2 graphes)

Personalisiertes Piktogramm in ComboView
Hier ein Beispiel der Erstellung eines Objekts mit verschiedenen Eigenschaften, verbunden mit einem persönlichen Piktogramm.

Download the example icon to place in same directory of the macro

The icon used is one icon to file disk, one icon to resource FreeCAD and one icon include in the macro (format .XPM)



Other complete example creation cube with icon in macro

Use QFileDialog for write the file
Complete code:

Use QFileDialog for read the file
Complete code:

Use QColorDialog for get the color
Complete code:

Some useful commands
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 or with the procedure

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

or with the procedure or or or