|
|
(26 intermediate revisions by 9 users not shown) |
Line 1: |
Line 1: |
− | == Qt Designer User Interfaces in KDE ==
| + | {{Note|This is now located at https://community.kde.org/Get_Involved/development/Tutorials/Using_Qt_Designer}} |
− | | |
− | In this tutorial, we will explore how to programatically insert user interfaces
| |
− | (UIs) created with Qt Designer, into your KDE project.
| |
− | | |
− | == Designing the UI ==
| |
− | | |
− | [http://www.trolltech.com/products/qt/features/designer Qt Designer] is a
| |
− | graphical program which allows you to easily build user interfaces, using an
| |
− | intuitive "drag n drop" interface. Designer has its own excellent
| |
− | [http://doc.trolltech.com/4.3/designer-manual.html user documentation].
| |
− | It might make sense to provide a brief example of using Designer here, but
| |
− | for now this article will leave most of that to the Designer manual itself.
| |
− | | |
− | == Adding the UI File to Your KDE Project ==
| |
− | | |
− | For our purposes, the most important part of using Designer is the
| |
− | <tt>*.ui</tt> file that it creates. This is simply an XML file that
| |
− | encodes the user interface in a machine-readable (and human-readable!) way.
| |
− | | |
− | Let's imagine that you've created a UI named "MyDialog" with Designer, and
| |
− | saved it as the file <tt>mydialog.ui</tt>. To add this UI to your KDE
| |
− | project, simply add a command like the following to your CMakeLists.txt file:
| |
− | | |
− | <code>
| |
− | kde4_add_ui_files(myapp_SRCS mydialog.ui)
| |
− | </code>
| |
− | | |
− | Replace "<tt>myapp_SRCS</tt>" with the name of the main block in
| |
− | your CMakeLists.txt file, defining all of the source code files. It is usually the
| |
− | name of your application, with "<tt>_SRCS</tt>" appended.
| |
− | | |
− | When you do this, the build system will run the Qt program <tt>uic</tt>
| |
− | on <tt>mydialog.ui</tt>, to auto-generate a C++ header file that
| |
− | defines the UI. The generated file will be named <tt>ui_mydialog.h</tt>.
| |
− | | |
− | == Using the UI in Your Code ==
| |
− | | |
− | The <tt>ui_mydialog.h</tt> file defines a class named
| |
− | "<tt>Ui_MyDialog</tt>", that contains all of the widgets you created in
| |
− | Designer as public members of the class. It also contains the public function
| |
− | "<tt>setupUi(QWidget *parent)</tt>", which instantiates all of the widgets,
| |
− | sets up their properties, and inserts them into layout managers, all according
| |
− | to what you specified in Designer.
| |
− | | |
− | Note that <tt>setupUi()</tt> takes a <tt>QWidget*</tt> | |
− | argument. This argument represents the parent container widget, into which
| |
− | all of the widgets in your UI will be inserted. In other words,
| |
− | '''<tt>Ui_MyDialog</tt> is not itself derived from QWidget''', and
| |
− | '''it does not contain a toplevel widget itself'''. You have to supply the toplevel widget
| |
− | when you call <tt>setupUi()</tt>. This is an important point.
| |
− | | |
− | One more important semantic detail: the <tt>Ui_MyDialog</tt> class
| |
− | also creates a <tt>Ui</tt> namespace, which simply creates an alias
| |
− | for the class. So you can use <tt>Ui::MyDialog</tt> to refer to the
| |
− | same class.
| |
− | | |
− | Now, on to actually using the generated UI in your code. The Qt documentation
| |
− | shows three ways of [http://doc.trolltech.com/latest/designer-using-a-component.html how to use ui-files];
| |
− | here only the ''direct approach'' is discussed. The goal is to create a KDialog
| |
− | which embeds the UI from the ui-file. First, we have to subclass MyDialog from
| |
− | KDialog and add a pointer to Ui::MyDialog. The header file of
| |
− | "<tt>mydialog.h</tt>" looks like the following:
| |
− | | |
− | <code cppqt>
| |
− | #ifndef MYDIALOG_H
| |
− | #define MYDIALOG_H
| |
− | | |
− | #include <KDialog>
| |
− | | |
− | // include the automatically generated header file for the ui-file
| |
− | #include "ui_mydialog.h"
| |
− | | |
− | class MyDialog : public KDialog
| |
− | {
| |
− | Q_OBJECT
| |
− | public:
| |
− | MyDialog( QWidget *parent=0 );
| |
− | ~MyDialog();
| |
− | | |
− | private slots:
| |
− | void slotButtonClicked();
| |
− | | |
− | private:
| |
− | // pointer to the ui. we can access all gui elements
| |
− | // specified in Designer. If mydialog.ui contains a
| |
− | // button "myButton", we will be able to access it
| |
− | // with ui.myButton in the cpp file.
| |
− | Ui::MyDialog ui;
| |
− | };
| |
− | | |
− | #endif
| |
− | </code>
| |
− | | |
− | Now we are going to look at the implementation of MyDialog, which is in the file
| |
− | "<tt>mydialog.cpp</tt>".
| |
− | | |
− | <code cppqt>
| |
− | #include <KLocale>
| |
− | #include <KMessageBox>
| |
− | | |
− | // include the header file of the dialog
| |
− | #include "mydialog.h"
| |
− | | |
− | MyDialog::MyDialog( QWidget *parent )
| |
− | : KDialog( parent ) | |
− | {
| |
− | QWidget *widget = new QWidget( this );
| |
− | | |
− | // create the user interface, the parent widget is "widget"
| |
− | ui.setupUi(widget); // this is the important part
| |
− | | |
− | // set the widget with all its gui elements as the dialog's
| |
− | // main widget
| |
− | setMainWidget( widget );
| |
− | | |
− | // other KDialog options
| |
− | setCaption( i18n("This is my Dialog window!") );
| |
− | setButtons( KDialog::Close );
| |
− | | |
− | // Example Signal/Slot connection using widgets in your UI.
| |
− | // Note that you have to prepend "ui." when referring
| |
− | // to your UI elements.
| |
− | connect( ui.myButton, SIGNAL( clicked() ),
| |
− | this, SLOT( slotButtonClicked() ) );
| |
− | } | |
− | | |
− | MyDialog::~MyDialog()
| |
− | {
| |
− | }
| |
− | | |
− | void MyDialog::slotButtonClicked()
| |
− | {
| |
− | KMessageBox::information( this,
| |
− | i18n("You pressed the button!" ),
| |
− | i18n( "Hooray!" ) );
| |
− | } | |
− | | |
− | #include "mydialog.moc"
| |
− | </code>
| |
− | | |
− | So, basically, we create a new Ui::MyDialog and then call
| |
− | <tt>ui.setupUi(widget)</tt> in the constructor of <tt>MyDialog</tt>. This
| |
− | places the UI elements into the given widget. Then we set the parent-widget
| |
− | as the KDialog's main widget. We can then interact with all of the UI elements
| |
− | by prepending "<tt>ui.</tt>" to their names, just like it is often done
| |
− | with the prefix "<tt>m_</tt>".
| |
− | | |
− | == Final Thoughts ==
| |
− | | |
− | The cascade of files and classes in this tutorial may seem daunting at
| |
− | first, but the naming scheme layed out here has one nice intuitive
| |
− | feature: the source code files that you will be editing directly (either as
| |
− | text or with Designer) are all named with the same scheme:
| |
− | * '''mydialog.ui''': the user interface, created with Designer
| |
− | * '''ui_mydialog.h''': auto-generated by uic, Qt's user interface compiler
| |
− | * '''mydialog.h/cpp''': the dialog implementation
| |
− | The steps in short are
| |
− | # create <tt>mydialog.ui</tt>
| |
− | # create <tt>mydialog.h/cpp</tt>
| |
− | # add variable Ui::MyDialog ui; in <tt>mydialog.h</tt>
| |
− | # call ui.setupUi(widget);</tt>
| |
− | # access the ui elements with <tt>ui.</tt>
| |
− | | |
− | == Qt Documentation ==
| |
− | | |
− | The Qt documentation contains a good article about
| |
− | [http://doc.trolltech.com/latest/designer-using-a-component.html Using a Component in Your Application].
| |
− | [[Category:C++]]
| |
− | [[Category:KDE4]]
| |