开始看起《C++ GUI Programming with Qt 4》这本书来,突然觉得看书时如果不做点笔记来学到的东西会很容易忘记,所以还是花点时间把东西记下来,以加深自己的理解,同时也能供自己以后进行查阅。
众所周知,在Qt的工具中有一个Qt Designer专门用来绘制软件UI。它可以让我们像VS中C#制作桌面程序时一样直接将控件拖曳到程序中对其进行排布,而不用再自己一个一个地写QLabel, QPushButton, 再用QLayout对它们进行布局。这样做不仅速度上会比手写代码快上许多,以后对布局进行修改也将是一件轻而易举的事情。接下来讲下这个UI设计器到底是怎么进行工作的。
在Qt Designer中绘制控件时,它最终其实也是生成一份记录布局外观信息的文本文件而已。就比如你用Dreamwaver设计网页时生成的HTML文件,用 Blend设计WPF外观时所生成的xaml文件一样,Qt Designer也会生成一份后缀名为ui, 以XML为格式的记录布局信息的文本文件。
以书中的跳转到单元格对话框为例,它生成的文本文件如下:
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>GoToCellDialog</class> <widget class="QWidget" name="GoToCellDialog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>223</width> <height>71</height> </rect> </property> <property name="windowTitle"> <string>Go to Cell</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> <item> <layout class="QHBoxLayout" name="horizontalLayout"> <item> <widget class="QLabel" name="label"> <property name="text"> <string>&Cell Location:</string> </property> <property name="buddy"> <cstring>lineEdit</cstring> </property> </widget> </item> <item> <widget class="QLineEdit" name="lineEdit"/> </item> </layout> </item> <item> <widget class="QDialogButtonBox" name="buttonBox"> <property name="standardButtons"> <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> </widget> </item> </layout> </widget> <tabstops> <tabstop>lineEdit</tabstop> </tabstops> <resources/> <connections/> </ui>
接下来讲的是Qt如何使用这个XML文件来创建布局和如何去使用这个UI文件。
在使用ui文件时,你需要在Qt中将这个ui文件以头文件的形式给包含进来,其格式为#include "ui_UI文件的名称.h"。在Qt Creator中按Ctrl键将这个文件打开,可以看到如下的内容。
#ifndef UI_GOTOCELLDIALOG_H #define UI_GOTOCELLDIALOG_H #include <QtCore/QVariant> #include <QtGui/QAction> #include <QtGui/QApplication> #include <QtGui/QButtonGroup> #include <QtGui/QDialogButtonBox> #include <QtGui/QHBoxLayout> #include <QtGui/QHeaderView> #include <QtGui/QLabel> #include <QtGui/QLineEdit> #include <QtGui/QVBoxLayout> #include <QtGui/QWidget> QT_BEGIN_NAMESPACE class Ui_GoToCellDialog { public: QVBoxLayout *verticalLayout; QHBoxLayout *horizontalLayout; QLabel *label; QLineEdit *lineEdit; QDialogButtonBox *buttonBox; void setupUi(QWidget *GoToCellDialog) { if (GoToCellDialog->objectName().isEmpty()) GoToCellDialog->setObjectName(QString::fromUtf8("GoToCellDialog")); GoToCellDialog->resize(223, 71); verticalLayout = new QVBoxLayout(GoToCellDialog); verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); horizontalLayout = new QHBoxLayout(); horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); label = new QLabel(GoToCellDialog); label->setObjectName(QString::fromUtf8("label")); horizontalLayout->addWidget(label); lineEdit = new QLineEdit(GoToCellDialog); lineEdit->setObjectName(QString::fromUtf8("lineEdit")); horizontalLayout->addWidget(lineEdit); verticalLayout->addLayout(horizontalLayout); buttonBox = new QDialogButtonBox(GoToCellDialog); buttonBox->setObjectName(QString::fromUtf8("buttonBox")); buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok); verticalLayout->addWidget(buttonBox); #ifndef QT_NO_SHORTCUT label->setBuddy(lineEdit); #endif // QT_NO_SHORTCUT retranslateUi(GoToCellDialog); QMetaObject::connectSlotsByName(GoToCellDialog); } // setupUi void retranslateUi(QWidget *GoToCellDialog) { GoToCellDialog->setWindowTitle(QApplication::translate("GoToCellDialog", "Go to Cell", 0, QApplication::UnicodeUTF8)); label->setText(QApplication::translate("GoToCellDialog", "&Cell Location:", 0, QApplication::UnicodeUTF8)); } // retranslateUi }; namespace Ui { class GoToCellDialog: public Ui_GoToCellDialog {}; } // namespace Ui QT_END_NAMESPACE #endif // UI_GOTOCELLDIALOG_H
通过这个文件,我们了解到:Qt在使用ui布局文件是其实将一个XML文件翻译成一个UI类。这个类中的成员是我们之前所拖曳的控件,而其中有一个setupUi的方法实际将这个布局给创建起来,就如同我们不使用Ui文件时自己手写代码将布局给创建起来一样。
知道了这点,我们也就知道该用什么方法来使用这个ui文件了。主要有以下两种方法:
一、创建ui类,比如上面这个例子:Ui::GoToCellDialog ui; 然后调用其中的setupUi方法并将要进行布局的控件,如对话框等作为参数传进去。
二、这也是最为常用的方法。既然其本身实际是一个类,那我们只要将这个类作为我们要对其进行布局的类的父类即可,然后在构造函数中调用继承到的setupUi方法便可将布局创建起来。