Dialog creation/it

In questa pagina vi mostreremo come creare una semplice finestra di dialogo di Qt con Qt Designer, lo strumento ufficiale di Qt per la progettazione di interfacce, quindi come convertirla in codice Python e poi utilizzarla all'interno di FreeCAD.

Nell'esempio si assume che sappiate già come modificare ed eseguire gli script di Python, e sappiate anche fare delle cose semplici in una finestra di terminale, come navigare, ecc.

Naturalmente, è necessario che PyQt sia installato.

Progettare la finestra
Nelle applicazioni CAD, il disegno di una buona UI (interfaccia utente) è molto importante. L'utente esegue quasi tutte le operazioni tramite qualche componente dell'interfaccia: legge le finestre di dialogo, preme i pulsanti, sceglie tra le icone, ecc. Quindi è molto importante pensare attentamente a ciò che si intende fare, a come si desidera che l'utente si comporti, e a quale sarà il flusso di lavoro delle proprie azioni.

Quando si progetta l'interfaccia, è bene tenere presenti alcune cose:


 * Finestre di dialogo modali e non-modali: una finestra di dialogo modale appare sullo schermo in primo piano, blocca l'azione della finestra principale e costringe l'utente a rispondere alla finestra di dialogo, mentre un dialogo non-modale permette di continuare a lavorare sulla finestra principale. In alcuni casi è meglio usare la prima soluzione, in altri casi no.
 * Identificare ciò che è necessario e ciò che è facoltativo. Accertarsi che l'utente sappia esattamente quello che deve fare. Etichettare tutto con una descrizione adeguata, realizzare dei suggerimenti per l'uso degli strumenti, ecc.
 * Separare i comandi dei parametri. Questo solitamente si ottiene con pulsanti e campi per inserire i testi. L'utente sa che cliccando su un pulsante si produce una azione, e che, invece, sostituendo un valore all'interno di un campo di testo si modifica un parametro da qualche parte. In genere, oggi gli utenti sanno bene che cosa è un pulsante, che cosa è un campo di input, ecc. Il toolkit Qt, che stiamo per usare, è il più avanzato strumento di costruzione di interfacce. Non dovrete preoccuparvi molto di fare le cose chiare, dal momento che sarà già esso stesso molto chiaro.

Ora che abbiamo definito con precisione quello che faremo, è il momento di aprire Qt Designer.

Disegneremo una finestra di dialogo molto semplice, simile a questa:



Dopo utilizzaremo questa finestra di dialogo all'interno di FreeCAD per produrre un bel piano rettangolare. Forse pensate che produrre dei bei piani rettangolari non è particolarmente utile, però, in un secondo tempo, sarà facile apportarvi delle modifiche e creare delle cose più complesse.

Quando viene aperto, Qt Designer ha questo aspetto:



È molto semplice da utilizzare.

Sulla barra di sinistra ci sono gli elementi che possono essere trascinati nel proprio widget (componente aggiuntivo).

Sul lato destro sono disposti i pannelli delle proprietà che mostrano tutti i tipi di proprietà modificabili degli elementi selezionati.

Per iniziare, creare un nuovo widget o complemento. Selezionare "Dialog without buttons", in quanto non vogliamo i pulsanti Ok e Annulla predefiniti. Quindi, trascinare nel proprio widget 3 labels (etichette), una per il titolo, una per inserire il testo "Altezza" e un'altra per inserire il testo "Larghezza". Le etichette sono semplici testi che appaiono nel widget, al solo scopo di informare l'utente. Quando si seleziona un'etichetta, sul lato destro appaiono diverse proprietà che volendo si possono modificare, come, ad esempio, lo stile del carattere, la sua altezza, ecc.

Poi, aggiungere 2 LineEdits, che sono campi di testo che l'utente può riempire, uno per l'altezza e uno per la larghezza. Anche di questi oggetti si possono modificare le proprietà. Ad esempio, perché non impostare un valore predefinito? Per esempio digitiamo 1,00 per ciascuno. In questo modo, quando l'utente vedrà la finestra di dialogo, entrambi i valori saranno già compilati e se gli vanno bene può premere direttamente il tasto, risparmiando tempo prezioso. Dopo, aggiungere un PushButton, che è il tasto che l'utente dovrà premere dopo aver compilato i 2 campi.

Notare che qui che ho scelto dei comandi molto semplici, ma Qt dispone di molte altre opzioni, ad esempio, è possibile utilizzare Spinboxes invece di LineEdits, ecc .. Date un'occhiata a ciò che è disponibile, vi verranno sicuramente altre idee.

Questo è tutto quello che si deve fare in Qt Designer.

Un'ultima cosa, però, rinominare tutti i propri elementi con nomi più adeguati, così negli script sarà più facile identificarli:



Convertire il dialogo in Python
Ora, salviamo il nostro widget da qualche parte. Esso verrà salvato come un file .ui, che potremo facilmente convertire in script di Python tramite pyuic. Su Windows, il programma pyuic è incluso con PyQt (da verificare), su Linux probabilmente è necessario installarlo separatamente tramite il proprio gestore di pacchetti (su sistemi debian-based è parte del pacchetto di strumenti PyQt4-dev-tools). Per fare la conversione, è necessario aprire una finestra di terminale (o una finestra del prompt dei comandi in Windows), portarsi nella cartella in cui si è salvato il file .ui, e digitare: On some systems the program is called pyuic4 instead of pyuic. This will simply convert the .ui file into a python script. If we open the mywidget.py file, its contents are very easy to understand: As you see it has a very simple structure: a class named Ui_Dialog is created, that stores the interface elements of our widget. That class has two methods, one for setting up the widget, and one for translating its contents, that is part of the general Qt mechanism for translating interface elements. The setup method simply creates, one by one, the widgets as we defined them in Qt Designer, and sets their options as we decided earlier. Then, the whole interface gets translated, and finally, the slots get connected (we'll talk about that later).

We can now create a new widget, and use this class to create its interface. We can already see our widget in action, by putting our mywidget.py file in a place where FreeCAD will find it (in the FreeCAD bin directory, or in any of the Mod subdirectories), and, in the FreeCAD python interpreter, issue: And our dialog will appear! Note that our python interpreter is still working, we have a non-modal dialog. So, to close it, we can (apart from clicking its close icon, of course) issue:

Making our dialog do something
Now that we can show and hide our dialog, we just need to add one last part: To make it do something! If you play a bit with Qt designer, you'll quickly discover a whole section called "signals and slots". Basically, it works like this: elements on your widgets (in Qt terminology, those elements are themselves widgets) can send signals. Those signals differ according to the widget type. For example, a button can send a signal when it is pressed and when it is released. Those signals can be connected to slots, which can be special functionality of other widgets (for example a dialog has a "close" slot to which you can connect the signal from a close button), or can be custom functions. The PyQt Reference Documentation lists all the qt widgets, what they can do, what signals they can send, etc...

What we will do here, is to create a new function that will create a plane based on height and width, and to connect that function to the pressed signal emitted by our "Create!" button. So, let's begin with importing our FreeCAD modules, by putting the following line at the top of the script, where we already import QtCore and QtGui: Then, let's add a new function to our Ui_Dialog class: Then, we need to inform Qt to connect the button to the function, by placing the following line just before QtCore.QMetaObject.connectSlotsByName(Dialog): This, as you see, connects the pressed signal of our create object (the "Create!" button), to a slot named createPlane, which we just defined. That's it! Now, as a final touch, we can add a little function to create the dialog, it will be easier to call. Outside the Ui_Dialog class, let's add this code: (Python reminder: the __init__ method of a class is automatically executed whenever a new object is created!) Then, from FreeCAD, we only need to do: That's all Folks... Now you can try all kinds of things, like for example inserting your widget in the FreeCAD interface (see the Code snippets page), or making much more advanced custom tools, by using other elements on your widget.

The complete script
This is the complete script, for reference:

Method 1
An example of a dialog box complete with its connections. Here the same window but with an icon on each button. Here the code to display the icon on the pushButton, change the name for another button, (radioButton, checkBox) and the path to the icon. The command UserAppData gives the user path AppHomePath gives the installation path of FreeCAD This command reverses the horizontal button, right to left.

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 The appellant, file that contains the window and your code.

The file my_file.py

The connections are to do, a good exercise.

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