First let's look at a small figure that shows the relationship between .ui files, generated code and application code:
Qt Designer reads and writes .ui files, e.g. form.ui. The user interface compiler, pyuic, creates an implementation file, e.g. form.py, from the .ui file. The application code in main.py imports a form. Typically main.py is used to instantiate the QApplication object and start off the event loop.
While this approach is simple, it isn't sufficient for more complex dialogs. Complex dialogs tend to have quite a lot of logic attached to the form's widgets, more logic than can usually be expressed with predefined signals and slots. One way of handling this extra logic is to write a controller class in the application code that adds functionality to the form. This is possible because pyuic generated classes expose a form's controls and their signals to the public space. The big disadvantage of this method is that it's not exactly Qt-style. If you were not using Qt Designer, you would almost always add the logic to the form itself, where it belongs.
This is why the capability of adding custom slots and member variables to a form was added to Qt Designer early on. The big additional benefit with this approach is that you can use Qt Designer to connect signals to those custom slots, in the same elegant graphical way that is used to connect signals to predefined slots. The uic then adds an empty stub for each custom slot to the generated form.py implementation file.
The big question now is how to add custom implementation code to those custom slots. Adding code to the generated form.py is not an option, as this file gets recreated by pyuic whenever the form changes -- and we don't want a combination of generated and handwritten code. There is an alternative solution, which we'll cover next.
A very clean way to implement custom slots for generated forms is via python inheritance as shown in the next figure:
Here the user wrote an additional class FormImpl, and the implementation file formimpl.py. The file imports the pyuic generated form and reimplements all the custom slots. This is possible because uic generated custom slots are virtual. In addition to implementing custom slots, this approach gives the user a way to do extra initialization work in the constructor of the subclass, and extra cleanups in the destructor.
Because of these benefits and its flexibility, this approach became the primary way of using Qt Designer in Qt 2.x.
Note: To keep the namespace clean, most users did not follow the Form and FormImpl naming scheme shown in the figure, but instead named their Qt Designer forms FormBase and their subclasses Form. This made a lot of sense, because they always subclassed and were using those subclasses in application code.
Step 1:
You have created your form in Qt Designer. You include the form in your project
(or create with Project->Add form). You need to generate a python implementation
of the form. To do it, press the right mouse button on the ui file in the project panel and
select "Generate py with pyuic".
Step 2:
Now you can see in the project panel sub item "maindialog.py".
It is implemented as a subitem for spliting your project files
and generated files. Useful when projects have a lot of forms
and your python files.
Step 3:
You have created an implementation file. You need to sub-class
the class of the designer form. To do it press the right mouse button on ui file
in project panel and select "Inherits".
Step 4:
Now you see a small wizard for subclassing classes created with pyuic.
Here you can enter the name of your new class and select a list of
virtual functions which you want to reimplement. You can open
a tree of inheritence and see all the functions that you can reimplement
(qt virtual functions).
Step 5:
After these operations you will have the following structure of classes:
© theKompany.com, Inc 2002-2003 |