|
|
(42 intermediate revisions by 13 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.2/designer-manual.html user documentation].
| |
| It might make sense to provide a brief example of using Designer here, but
| |
| for now I 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 myialog.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*)</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. There are a few ways
| |
| to do this; for now I will only discuss one method, in which we create a class
| |
| that inherits from both <tt>Ui::MyDialog</tt> and a Qt container class
| |
| like {{qt|QFrame}}. Create a class definition file named
| |
| "<tt>mydialog.h</tt>", and add the following:
| |
| | |
| <code cppqt>
| |
| #ifndef MYDIALOG_H
| |
| #define MYDIALOG_H
| |
| | |
| #include <kdialog.h>
| |
| #include "ui_mydialog.h"
| |
| | |
| class MyDialogUI : public QFrame, public Ui::MyDialog
| |
| {
| |
| Q_OBJECT
| |
| public:
| |
| MyDialogUI( QWidget *parent=0 );
| |
| };
| |
| | |
| class MyDialog : public KDialog
| |
| {
| |
| Q_OBJECT
| |
| public:
| |
| MyDialog( QWidget *parent=0 );
| |
| ~MyDialog();
| |
| | |
| private slots:
| |
| void slotButtonClicked();
| |
| | |
| private:
| |
| MyDialogUI *ui;
| |
| };
| |
| | |
| #endif
| |
| </code>
| |
| | |
| So we have defined two classes. <tt>MyDialogUI</tt> is simply a
| |
| {{qt|QFrame}} with your UI elements placed inside it.
| |
| <tt>MyDialog</tt> is a {{kde|KDialog}} window, whose main
| |
| widget will be the <tt>MyDialogUI</tt> instance named
| |
| <tt>ui</tt> above. Here is the "<tt>mydialog.cpp</tt>"
| |
| C++ definition file:
| |
| | |
| <code cppqt>
| |
| #include <klocale.h>
| |
| #include <kmessagebox.h>
| |
| | |
| #include "mydialog.h"
| |
| | |
| MyDialogUI::MyDialogUI( QWidget *parent )
| |
| : QFrame( parent )
| |
| {
| |
| setupUi( this );
| |
| }
| |
| | |
| MyDialog::MyDialog( QWidget *parent )
| |
| : KDialog( parent )
| |
| {
| |
| ui = new MyDialogUI( this );
| |
| setMainWidget( ui );
| |
| 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 widgets.
| |
| connect( ui->MyButton, SIGNAL( clicked() ), this, SLOT( slotButtonClicked() ) );
| |
| } | |
| | |
| MyDialog::~MyDialog()
| |
| {
| |
| delete ui;
| |
| } | |
| | |
| void MyDialog::slotButtonClicked()
| |
| {
| |
| KMessageBox::information( this, i18n("You pressed the button!" ), i18n( "Hooray!" ) );
| |
| }
| |
| | |
| #include "mydialog.moc"
| |
| </code>
| |
| | |
| So, basically, we call <tt>setupUi(this)</tt> in the <tt>MyDialogUI</tt>
| |
| constructor, which places your UI elements into that widget. Then, in the
| |
| <tt>MyDialog</tt> constructor, we create the <tt>MyDialogUI</tt>
| |
| instance named <tt>ui</tt> and set it to be our dialog's main widget.
| |
| We can then interact with all of the UI elements by prepending
| |
| "<tt>ui-></tt>" to their names.
| |
| | |
| === Final Thoughts ===
| |
| | |
| The cascade of files and classes in this tutorial may seem daunting at
| |
| first, but the naming scheme I've layed out here has one nice intuitive
| |
| feature: the three source code files that you will be editing
| |
| directly (either as text or with Designer) are all named with the same
| |
| simple filename stem: <tt>mydialog.ui</tt>, <tt>mydialog.h</tt>, and
| |
| <tt>mydialog.cpp</tt>. Just remember that you'll be using the
| |
| <tt>MyDialog</tt> class almost exclusively. Setting up the
| |
| <tt>MyDialogUI</tt> class is easy (it only contains a one-line
| |
| constructor), and once it's set up you can pretty well ignore it.
| |