Qt的设计初衷就是为了能够直观并且友好地进行手工编码,对于程序员来说,纯粹通过编写C++源代码来开发整个Qt应用程序并不稀奇。尽管如此,许多程序员还是喜欢使用可视化的方法来设计窗体,因为他们发现使用可视化方式会比手工编码显得更自然、更快速,并且也希望能够通过可视化方法,对那些手工编码所设计的窗体,进行更快速、更容易的测试和修改。
Q设计师( Qt Designer)为程序员们提供了可供使用的新选择,它提供一种可视化的设计能力。Qt设计师可用于开发应用程序中的所有或部分窗体。使用Qt设计师所创建的窗体最终仍旧是C++代码,因此,可把Qt设计师看作是一个传统的工具集,并且不会对编译器强加其他特殊要求。
无论是使用手工编码还是使用Qt设计师,创建对话框时总是要包含以下这几个相同的基本步骤:
- 创建并初始化子窗口部件。
- 把子窗口部件放到布局中。
- 设置Tab键顺序(窗口部件接收焦点的顺序)。
- 建立信号-槽之间的连接。
- 实现对话框中的自定义槽。
以下是使用ui文件的代码:
#include <QApplication>
#include <QDialog>
#include "ui_gotocelldialog.h"
int main(int argc, char *argv[])
{
#if 1
QApplication app(argc, argv);
Ui::GoToCellDialog ui;
QDialog *dialog = new QDialog;
ui.setupUi(dialog);
dialog->show();
return app.exec();
#endif
}
qmake工具可以自动检测到用户界面文件(***.ui文件)并且可以生成适当的makefile规则来调用Qt的用户界面编译器(user interface compiler,uic)。uic工具会将**.ui文件转换成C++并且将转换结果存储在ui_**.h文件中。
所生成的ui_**.h文件中包含了类Ui::XXX的定义,该类是一个与**.ui文件等价的C++文件。这个类声明了一些成员变量,它们存储着窗体中的子窗口部件和子布局,以及用于初始化窗体的 setupUi()成员函数。
Ui::XXX类的定义如下:
class Ui_XXX
{
public:
QVBoxLayout *vboxLayout;
QHBoxLayout *hboxLayout;
QLabel *label;
QLineEdit *lineEdit;
QHBoxLayout *hboxLayout1;
QSpacerItem *spacerItem;
QPushButton *okButton;
QPushButton *cancelButton;
void setupUi(QWidget *GoToCellDialog)
{
...
}
...
生成的类没有任何基类。当在main.cpp文件中使用该窗体时,可以创建一个 QDialog对象,然后把它传递给 setupUi()函数。
如果现在运行该程序,对话框也可以工作,但它并没有正确地实现所想要的那些功能:
- OK按钮总是失效的。
- Cancel按钮什么也做不了。
- 行编辑器可以接受任何文本,而不是只能接受有效的单元格位置坐标。
通过写一些代码,就可以让对话框具有适当的功能。最为简捷的做法是创建一个新类,让该类同时从QDialog和Ui::XXX中继承出来,并且由它来实现那些缺失的功能(从而也证明了这句话:通过简单地增加另外一个间接层就可以解决软件的任何问题)。命名惯例是:将该类与uic所生成的类具有相同的名字,只是没有Ui::前缀而已,在该类的构造函数中调用Ui::XXX的setUi()成员函数实现窗口创建,然后再决定每一个子部件的行为。因为多重继承的关系,XXX类中可以直接访问Ui::XXX的所有成员。setUi()成员可以自动将子部件的信号和符合一定命名规则的槽函数进行连接。