The Evolution of Qt Designer

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Image:qt-logo_new.png Image:qq-title-article.png
Qt Quarterly | Выпуск 14 | Документация


by Trenton Schulz

Qt Designer supplied with Qt 4.0 comprises many features that makes itthe fastest and easiest way to lay out and design forms. In this article,we'll take a look at the history of Qt Designer and some of the newfeatures and design decisions in Qt 4.0.

Содержание

Early GUI Builders

The Qt API has always made it easy to create a form. Using layoutmanagers, we can create forms relatively quickly. Still, thisapproach can rapidly become tedious if you have many forms to create.There's also the "edit, compile, run" cycle as you check thepositioning of widgets. During all of this you may start to thinkthat there really should be a GUI for making your GUI.

Already with Qt 1, there were a few GUI builders available as opensource software, with varying levels of layout and widget support.

  • Qt Architect, developed by Jeff Harris and Klaus Ebner,allowed you to lay out the widgets, edit pixmaps for icons, and editcode for the forms. It was probably the most commonly used GUIbuilder for versions 1 and 2 of Qt.
  • QtEZ, created by Sam Magnuson and later maintained by JanProkop, allowed you to develop most of your application withoutleaving the program. It could even generate a main()function for you.
  • Ebuilder, by Ernie van der Meer, focused on theparent--child relationships of widgets and on building thesehierarchies.

Still, our users kept asking for a tool that was supported byTrolltech and that would always be synchronized with Qt releases.Also, early versions of these tools only offered manual placement forchild widgets, a major obstacle to cross-platform development.

The First Designer

Trolltech released Qt Designer 1.0 at the same time as Qt 2.2.From day one, dialogs created in Qt Designer were stored inwell-structured XML files (.ui files) that a separate tool, theUser Interface Compiler (uic), converted into C++ code. Qtapplications could also create forms based on .ui files atrun-time, using the QWidgetFactory class.

Qt Designer 1.0 also had the ability to define signals and slotsand to connect them together. The actual implementation of the slotswas done by subclassing the uic-generated classes andreimplementing the slots, which were declared virtual by uic. Thediagram below summarizes the situation. center

The first version of Qt Designer also provided full support forhorizontal, vertical, and grid layouts. Qt developers could rapidlyadd child widgets to a form, snap them into a layout, and see howthey would behave when the user resized the dialog. This immediatefeedback cut out the "edit, compile, run" cycle of laying outwidgets. center

It wasn't all rosy, though. Support for custom widgets was verylimited; they were rendered as a static image in the form, making ithard to tell how the actual form would behave without building it.Additionally, the subclassing technique was somewhat cumbersome (asthe diagram above illustrates) and required two classes, both withthe Q_OBJECT macro, resulting in needless overhead onQt/Embedded. Finally, Qt Designer 1.0 didn't support thecreation of main windows with menus and toolbars.

The Second Designer

Qt Designer 2.0 was released with Qt 3.0. It offered many featuresthat set it apart from the original Qt Designer. First, it alloweddevelopers to cut subclassing by using the .ui.h mechanism. The.ui.h file was included by the uic-generated source andallowed you to reimplement slots and even deal with construction anddestruction of the form.

center

A code editor was included inside of Qt Designer to edit the.ui.h file. Furthermore, there was a Source tab thatallowed you to add member variables, includes, and forwarddeclarations, in addition to signals and slots.

The second Qt Designer could also load several types of plugin.Widget plugins allowed you to create a plugin of your custom widget,making it possible to see the widget when using it on aform and access its properties. Another use of plugins was for wizards.It was even possible to connect to databases from insideQt Designer and view their data.

In addition, Qt Designer 2.0 included a .pro file parser,enabling you to manage your project from Qt Designer and to usethe built-in code editor to edit your source files. Some usersdeveloped entire applications using Qt Designer.

Making a Better Designer for Qt 4

Qt Designer was now an integral part of Qt, but there were stillthings that could be done to make it better. For instance, the codeeditor missed such features as being able to go to a specified line.There were also synchronization issues if you were editing a.ui.h file outside Qt Designer.

Another issue with Qt Designer was that it couldn't be integratedinto existing IDEs. This meant that developers who enjoyed theproductivity of IDEs had to leave it to use Qt Designer. Also,adding signals, slots, data members, declaration and implementationincludes, and more inside the Source tab was usuallyconsidered more troublesome than just editing the source filesdirectly.

All this and more lead to the work that would be part of the nextQt Designer. Many concepts needed to be revisited. As a result,an early glimpse of Qt Designer was part of the first Qt 4 beta. Asecond version containing a more complete feature set was introducedin beta 2 of Qt 4. The version contained in Qt 4's Release Candidateshould be almost identical to that in the final Qt 4 release. Let'stake a look at some of the features that are part of the new QtDesigner.

Better Integration with Existing IDEs

Qt Designer has now been fully compartmentalized to make itpossible to integrate it with existing IDEs. This means that you cancreate a form, edit its properties with the property editor, doubleclick on a widget, and be taken to a slot that a widget's signalconnects to, all without leaving the IDE.

For Qt 4.0, a Visual Studio .NET integration is available. Workon integration with other IDEs, notably KDevelop and Eclipse, isplanned for later Qt 4 releases.

New File Generation Model

Like before, Qt Designer still writes out .ui files thatcontain the specification of an interface, and uic generates C++code based on the .ui file. What has changed is that uic nowgenerates a simple struct containing all the widgets and asetupUi() function that creates the widgets and layouts. Thestruct does not inherit from QObject and is entirely definedin a header file.

There are three approaches to using a form in your application,reflecting the various ways in which standard C++ classes canbe combined together.

  • In the direct approach, you simply construct a widget to use as aplaceholder for the component, and set up the user interface inside it. For example:
#include "ui_myform.h" // defines the Ui::MyForm struct
 
int main(int argc, char *argv[])
{
    ...
    QDialog dialog;
    Ui::MyForm ui;
    ui.setupUi(&dialog);
    dialog.show();
    ...
  • In the single-inheritance approach, you subclass the form's base class( QWidget or QDialog, for example), and include a private instance ofthe form's user interface object. For example:
#ifndef MYFORM_H
#define MYFORM_H
 
#include "ui_myform.h"
 
class MyForm : public QDialog
{
    Q_OBJECT
 
public:
    MyForm(QWidget *parent = 0) : QDialog(parent)
    { ui.setupUi(this);
 
private slots:
    void on_inputSpinBox_valueChanged(int value);
 
private:
    Ui::MyForm ui;
};
 
#endif
  • In the multiple-inheritance approach, you subclass from both theform's base class and the form's user interface object. This allows thewidgets defined in the form to be used directly from within the scope ofthe subclass. For example:
#ifndef MYFORM_H
#define MYFORM_H
 
#include "ui_myform.h"
 
class MyForm : public QDialog, public Ui::MyForm
{
    Q_OBJECT
 
public:
    MyForm(QWidget *parent = 0) : QDialog(parent)
    { setupUi(this);
 
private slots:
    void on_inputSpinBox_valueChanged(int value);
};
 
#endif
The diagram below summarizes how the various files fit together usingsingle or multiple inheritance.This is very similar to subclassing with previous versions of QtDesigner, but this time only one Q_OBJECT class is necessary anduic needs only to generate one file (ui_myform.h).

center

Another novelty of Qt 4 is that slots that follow a certain namingconvention are automatically connected by uic. The namingconvention is on_objectName_signalName(), whereobjectName is the name of the child widget that emits the signal and signalName the name of the signal.

To handle .ui files created with earlier versions of QtDesigner, Qt 4 includes a tool called uic3 that converts old.ui files to the new format (with some help from theQt3Support library).

Easier Layout Manipulation

Previously, when you wanted to add a widget to an existing layout,you first had to break the old layout, add your widget, and thenreapply the layout. With the new Qt Designer, you can simply dragyour widget onto the form and if there is a layout, it isautomatically inserted into it. Hints help you determine where the widgetwill end up in the layout.

The grid layout in particular has been improved. Instead of somemagic routine that appeared to pick correct positions for widgets,you have the ability to drop the widgets where you please.In addition, you can manipulate the widgets already in the layout sothat they have proper stretch factors. It's never been easier to haveone widget take the place of two in a layout.

center

The new Qt Designer still lets you add widgets to a form and thengroup them in a layout. In addition, it is now possible to add thelayout first and then add your widgets to the layout.

More Intuitive User Interface

Qt Designer now makes extensive use of drag and drop. This allowsus to show a preview of the widget the moment you start the draginstead of just guessing where you want the widget to go. Italso allows the user to quickly clone widgets on a form and drag themto other forms.

It is now possible to create custom widgets on the fly that are just acombination of other widgets, simply by dragging them from the form tothe tool box. Qt Designer will remember these widgetsand make them usable in future forms. The drag and drop interfacealso makes it possible to drop a widget into an already existinglayout and to move widgets around in a grid layout.

Qt Designer now also shows an overview of the connections betweenwidgets. Changing to connection mode will show all the currentconnections. You can then add new ones by dragging connectionlines between them.

We have also made it possible to change the interface of QtDesigner. The trusty old MDI interface is still present, thoughchanged a bit. It is complemented by a new interface that usestop-level windows. If you aren't sure which one you like, you canswitch between them on the fly.

Easier Plugins

In addition to being embeddable, Qt Designer is also extensiblethrough plugins. There are interfaces for custom widgets, for specialwidget editors, for special preferences, and even for your own QtDesigner components. In fact, several of the Qt3Support widgetsare provided through plugins. Some examples of how to write your ownwidget plugins are included in examples/designer.

This is made possible by Qt 4's generic plugin mechanism. In Qt 3,only five types of plugins were supported (image format, SQL driver,style, text codec, and widget plugins). In Qt 4, arbitrary pluginsare possible by inheriting from an arbitrary interface and declaringthe plugin using the Q_EXPORT_PLUGIN() macro. Qt Designerwill then be able to use qobject_cast<>() and load the plugin. Seethe QPluginLoader class documentation for details.

Conclusion

We have seen the evolution of Qt Designer from some ideasdeveloped by a handful of devoted open source developers to afull-fledged supported application provided by Trolltech which hasbecome an essential tool for creating Qt applications. We encourageyou to give it a try in the next version of Qt 4.