《qt基础入门教程.pdf》由会员分享,可在线阅读,更多相关《qt基础入门教程.pdf(100页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、1.1 从从 Hello Qt 开始开始差不多所有的程序教材都从 Hello 开始,下面就是这个程序的 qt 版本。1#include 2#include 3 int main(int argc,char*argv)4 5QApplication app(argc,argv);6QLabel*label=new QLabel(Hello Qt!);7label-show();8return app.exec();9 按行解析以上 9 行代码第一,二行:是代码中需要使用的类的头文件。在 Qt4 中,可以写成的格式,当然也可写成“QApplication.h”。第三行:是 main 函数的标准写法
2、第五行:创建一个 QApplication 对象,管理应用程序的资源。第六行:QLabel 对象,QLabel 是一个 Qt 提供的小控件,显示一行文本。第七行:显示 QLabel。第八行:QApplication.exec(),让程序进入消息循环。等待可能的菜单,工具条,鼠标等的输入,进行响应。将以上代码放到名为 hello.cpp 中,保存,编译过程如下:qmake-project,qmake 命令创建 hello.pro,是平台无关的工程文件。在 hello.pro 所在目录下,运行 make(unix)或者 nmake(windows)。第 6 行代码还可以如下替换:QLabel*la
3、bel=new QLabel(Hello Qt!);这里面包含了 html 文本,显示的字体,颜色会改变。实际程序中,下面两行是比不可少的。QApplication app(argc,argv);return app.exec();1.2 连接信号和响应函数连接信号和响应函数连接信号和响应函数这个例子用来说明怎么响应信号,和 hello 程序的源代码相似,原来的 Label 用一个按钮代替,点击时退出程序。源程序如下:1#include 2#include 3 int main(int argc,char*argv)4 5QApplication app(argc,argv);6QPushBu
4、tton*button=new QPushButton(Quit);7QObject:connect(button,SIGNAL(clicked(),8&app,SLOT(quit();9button-show();10return app.exec();11 当有所动作或者状态改变,qt 的控件会发出消息(signal),例如,当点击按钮时,按钮会发送 clicked()消息,这个消息可以连接到一个函数上(这个函数在这里成为 slot)。这样,当一个消息发送时,slot 函数可以自动执行。在这个例子中,我们连接了按钮的 clicked 信号和 QApplication 的 quit函数,语法
5、如第七,八行所示。编译以上程序,将以上代码放在 quit.cpp 文件中,保存。依次运行qmake-projectqmake quit.promake(unix or linux)or nmake(windows)然后运行程序,点击 Quit 按钮,程序将会中止。1.3 控件的几何排列控件的几何排列Laying Out Widgets在这个小节中,我们说明在一个窗口中如何排列多个控件。学习利用 signal 和 slot 的方法使控件同步。程序要求用户通过 spin box 或者 slider 输入年龄。程序中使用了三个控件:QSpinBox,QSlider和QWidget。QWidget是这
6、个程序的主窗口。QSpinBox和QSlider被放在QWidget中;他们是QWidget的 children。反过来,我们也可以称 QWidget 是 QSpinBox 和 QSlider 的 parent。QWidget 没有 parent,因为它是程序的顶层窗口。在 QWidget及其子类的构造函数中,都有一个 QWidget*参数,用来指定它们的父控件。源代码如下:1#include 2#include 3#include 4#include 5 int main(int argc,char*argv)6 7QApplication app(argc,argv);8QWidget*w
7、indow=new QWidget;9window-setWindowTitle(Enter Your Age);10QSpinBox*spinBox=new QSpinBox;11QSlider*slider=new QSlider(Qt:Horizontal);12spinBox-setRange(0,130);13slider-setRange(0,130);14QObject:connect(spinBox,SIGNAL(valueChanged(int),15slider,SLOT(setValue(int);16QObject:connect(slider,SIGNAL(value
8、Changed(int),17spinBox,SLOT(setValue(int);18spinBox-setValue(35);19QHBoxLayout*layout=new QHBoxLayout;20layout-addWidget(spinBox);21layout-addWidget(slider);22window-setLayout(layout);23window-show();24return app.exec();25 第 8,9 行建立程序的主窗口控件,设置标题。第 10 到 13 行创建主窗口的 children,并设置允许值的范围。第 14 到第 17 行是 spi
9、nBox 和 slider的连接,以使之同步显示同一个年龄值。不管那个控件的值发生变化,都会发出 valueChanged(int)信号,另一个控件的 setValue(int)函数就会为这个控件设置一个新值。第 18 行将 spinBox 的值设置为 35,这时 spinBox 发出 valueChanged(int)信号,int 的参数值为 35,这个参数传递给 slider 的 setValue(int)函数,将 slider 的值也设置为 35。同理,slider 也会发出 valueChanged(int)信号,触发 spinBox 的 setValue(int)函数。这个时候,因为
10、 spinBox 的当前值就是 35,所以 spinBox 不会发送任何信号,不会引起死循环。在第 19 至 22 行,我们使用了一个布局管理器排列 spinBox 和 slider 控件。布局管理器能够根据需要确定控件的大小和位置。Qt 有三个主要的布局管理器:QHBoxLayout:水平排列控件。QVBoxLayout:垂直排列控件。QGridLayout:按矩阵方式排列控件第 22 行,QWidget:setLayout()把这个布局管理器放在 window 上。这个语句将 spinBox 和 slider 的“父”设为 window,即布局管理器所在的控件。如果一个控件由布局管理器确定
11、它的大小和位置,那个创建它的时候就不必指定一个明确的“父”控件。现在,虽然我们还没有看见 spinBox 和 slider 控件的大小和位置,它们已经水平排列好了。QHBoxLayout 能合理安排它们。我们不用在程序中考虑控件在屏幕上的大小和位置这些头疼的事情了,交给布局管理器就万事大吉。在 Qt 中建立用户界面就是这样简单灵活。程序员的任务就是实例化所需要的控件,按照需要设置它们的属性,把它们放到布局管理器中。界面中要完成任务由 Qt 的 signal 和 slot 完成。第二章第二章 创建对话框(创建对话框(Creating Dialogs)在这章介绍如何创建 Qt 的对话框。对话框是程
12、序和用户交互的桥梁,提供了程序和用户之间对话的一种方式。很多程序都是由一个主窗口,在这个主窗口中包含一个菜单条,多个工具条,和足够多的对话框。也有些程序本身就是一个对话框,直接相应用户的输入请求。本章中我们首先会用代码的方式创建我们的第一个对话框,然后用 Qt Designer 工具创建对话框。Qt Designer 是一个可视化的工具,用它可以更快的创建,修改对话框。2.1 派生对话框类(派生对话框类(Subclassing QDialog)第一个例子是一个用 C+实现的查找对话框。我们把这个对话框实现为一个类,这样它就是一个独立的控件,并有自己的信号(signal)和 slot 函数类的源
13、代码分别放在 finddialog.h 和 finddialog.cpp 中。首先看 finddialog.h 的代码1#ifndef FINDDIALOG_H2#define FINDDIALOG_H3#include 4 class QCheckBox;5 class QLabel;6 class QLineEdit;7 class QPushButton;8 class FindDialog:public QDialog9 10Q_OBJECT11 public:12FindDialog(QWidget*parent=0);13 signals:14void findNext(const
14、 QString&str,Qt:CaseSensitivity cs);15void findPrevious(const QString&str,Qt:CaseSensitivity cs);16 private slots:17void findClicked();18void enableFindButton(const QString&text);19 private:20QLabel*label;21QLineEdit*lineEdit;22QCheckBox*caseCheckBox;23QCheckBox*backwardCheckBox;24QPushButton*findBu
15、tton;25QPushButton*closeButton;26;27#endif一共 27 行,第 1,2,27 行是为了避免头文件被多次包含。第 3 行包含 QDialog 头文件,这个类从 QDialog 继承,QDialog 从 QWidget 继承。第 4 至 7 行是用到的 Qt 中类的前向声明。通过前向声明,编译器就知道这个类已经存在,而不用写出包含的头文件。这个问题稍后还要讲。第 8 至 26 行是类 FindDialog 的定义。第 10 行,Q_OBJECT 是一个宏定义,如果类里面用到了 signal 或者 slots,就要声明这个宏。第 12 行,FindDialog
16、(QWidget*parent=0);构造函数是 Qt 控件类的标准格式,默认的父参数为 NULL,说明没有父控件。第 13 行,signal 声明了这个对话框发出的两个信号,如果选择向前查找,那么对话框就发出 findPrevious()信号,否则,发出 findNext()信号。signal也是一个宏,在编译之前,C+预处理把它变成标准的 c+代码。Qt:CaseSensitivity 是一个枚举类型,有 Qt:CaseSensitive 和Qt:CaseInsensitive 两个值。在类的私有部分,声明有两个 slot 函数。为了实现这两个函数,需要用到对话框的其他控件的信息,所以保存
17、了一些控件的指针。slot 关键字和 signal一样,也是一个宏。对于私有成员变量,我们只是使用了它们的指针,没有对它们进行存取操作,编译器不需要知道它们的详细定义,所以只使用了这些类的前向声明。当然,也可以使用,等,但是,使用前向声明会让编译速度更快一些。下面看一下 finddialog.cpp 源文件代码:文件头和构造函数部分1#include 2#include finddialog.h3 FindDialog:FindDialog(QWidget*parent)4:QDialog(parent)5 6label=new QLabel(tr(Find&what:);7lineEdit=
18、new QLineEdit;8label-setBuddy(lineEdit);9caseCheckBox=new QCheckBox(tr(Match&case);10backwardCheckBox=new QCheckBox(tr(Search&backward);11findButton=new QPushButton(tr(&Find);12findButton-setDefault(true);13findButton-setEnabled(false);14closeButton=new QPushButton(tr(Close);15connect(lineEdit,SIGNA
19、L(textChanged(const QString&),16this,SLOT(enableFindButton(const QString&);17connect(findButton,SIGNAL(clicked(),18this,SLOT(findClicked();19connect(closeButton,SIGNAL(clicked(),20this,SLOT(close();21QHBoxLayout*topLeftLayout=new QHBoxLayout;22topLeftLayout-addWidget(label);23topLeftLayout-addWidget
20、(lineEdit);24QVBoxLayout*leftLayout=new QVBoxLayout;25leftLayout-addLayout(topLeftLayout);26leftLayout-addWidget(caseCheckBox);27leftLayout-addWidget(backwardCheckBox);28QVBoxLayout*rightLayout=new QVBoxLayout;29rightLayout-addWidget(findButton);30rightLayout-addWidget(closeButton);31rightLayout-add
21、Stretch();32QHBoxLayout*mainLayout=new QHBoxLayout;33mainLayout-addLayout(leftLayout);34mainLayout-addLayout(rightLayout);35setLayout(mainLayout);36setWindowTitle(tr(Find);37setFixedHeight(sizeHint().height();38 到这里 FindDialog 的构造函数就完成了。在传见控件和布局时我们使用了 new,一般情况下,我们还需要写析构函数 delete 这些控件。但是在 Qt 中这是不需要的,
22、当父控件销毁时,Qt 自动删除它所有的子控件和布局。下面是 FindDialog 类的两个 slot 函数:39 void FindDialog:findClicked()40 41QString text=lineEdit-text();42Qt:CaseSensitivity cs=43caseCheckBox-isChecked()?Qt:CaseSensitive44:Qt:CaseInsensitive;45if(backwardCheckBox-isChecked()46emit findPrevious(text,cs);47 else 48emit findNext(text,
23、cs);4950 51 void FindDialog:enableFindButton(const QString&text)52 53findButton-setEnabled(!text.isEmpty();54 当用户点击 findButton 按钮,findClicked()就会调用,根据 backwardCheckBox 状态,他发出 findPrevious()或者 findNext()信号。emit 也是一个 Qt 的宏。当用户改变 lineEdit 中的文本,enableFindButton()slot 函数就会调用。如果输入了文本,那么让 findButton 有效,否则就
24、无效。最后,创建 main.cpp 测试 FindDialog 对话框。1#include 2#include finddialog.h3 int main(int argc,char*argv)4 5QApplication app(argc,argv);6FindDialog*dialog=new FindDialog;7dialog-show();8return app.exec();9 运行 qmake 编译程序。由于在 FindDialog 中包含了 Q_OBJECT 宏,由 qmake 生成的 makefile 会保换特殊的规则运行 moc(Qt 的原对象编译器)。为了确保 moc
25、 正确工作,类定义必须放在头文件而不能放在实现文件中。由 moc 生成的代码中包含这个头文件,并加入它自己实现的 C+代码。使用了 Q_OBJECT 宏的类必须运行 moc。如果使用 qmake,那么 makefile 里自动包含相关的规则。如果忘记了运行 moc,就会发生连接错误。不同的编译器给出的提示信息不同,有的会非常晦涩。GCC 给出的错误信息如下:finddialog.o:In function FindDialog:tr(char const*,char const*):/usr/lib/qt/src/corelib/global/qglobal.h:1430:undefined
26、reference toFindDialog:staticMetaObjectVisual C+中的输出是这样:finddialog.obj:error LNK2001:unresolved external symbolpublic:virtual int _thiscall MyClass:qt_metacall(enum QMetaObject:Call,int,void*)这时需要重新运行 qmake,更新 makefile,然后编译程序。运行程序,如果看到了快键,测试 ALT+W,ALT+C,ALT+B,ALT+F 引发相应的处理程序。使用 TAB 键在将焦点改变到不同的控件上。默认
27、的 TAB 键是控件创建的顺序。QWidget:setTabOrder()可以改变这个顺序。提供合适的 tab 顺序和快键可以让用户不用鼠标也可以运行程序,通过键盘可以快速控制程序。2.2 深入信号和槽(深入信号和槽(Signals and Slots in Depth)信号和槽是 Qt 编程的一个重要部分。这个机制可以在对象之间彼此并不了解的情况下将它们的行为联系起来。在前几个例程中,我们已经连接了信号和槽,声明了控件自己的信号和槽,并实现了槽函数,发送了信号。现在来更深入了解这个机制。槽和普通的 c+成员函数很像。它们可以是虚函数(virtual),也可被重载(overload),可以是公
28、有的(public),保护的(protective),也可是私有的(private),它们可以象任何 c+成员函数一样被调用,可以传递任何类型的参数。不同在于一个槽函数能和一个信号相连接,只要信号发出了,这个槽函数就会自动被调用。connect 函数语法如下:connect(sender,SIGNAL(signal),receiver,SLOT(slot);sender 和 receiver 是 QObject 对象指针,signal 和 slot 是不带参数的函数原型。SIGNALE()和 SLOT()宏的作用是把他们转换成字符串。在目前有的例子中,我们已经连接了不同的信号和槽。实际使用中还
29、要考虑如下一些规则:1、一个信号可以连接到多个槽:connect(slider,SIGNAL(valueChanged(int),spinBox,SLOT(setValue(int);connect(slider,SIGNAL(valueChanged(int),this,SLOT(updateStatusBarIndicator(int);当信号发出后,槽函数都会被调用,但是调用的顺序是随机的,不确定的。2、多个信号可以连接到一个槽connect(lcd,SIGNAL(overflow(),this,SLOT(handleMathError();connect(calculator,SIGN
30、AL(divisionByZero(),this,SLOT(handleMathError();任何一个信号发出,槽函数都会执行。3、一个信号可以和另一个信号相连connect(lineEdit,SIGNAL(textChanged(const QString&),this,SIGNAL(updateRecord(const QString&);第一个信号发出后,第二个信号也同时发送。除此之外,信号与信号连接上和信号和槽连接相同。4、连接可以被删除disconnect(lcd,SIGNAL(overflow(),this,SLOT(handleMathError();这个函数很少使用,一个对象
31、删除后,Qt 自动删除这个对象的所有连接。信号和槽函数必须有着相同的参数类型,这样信号和槽函数才能成功连接:connect(ftp,SIGNAL(rawCommandReply(int,const QString&),this,SLOT(processReply(int,const QString&);如果信号里的参数个数多于槽函数的参数,多余的参数被忽略:connect(ftp,SIGNAL(rawCommandReply(int,const QString&),this,SLOT(checkErrorCode(int);如果参速类型不匹配,或者信号和槽不存在,在 debug 状态时,Qt
32、会在运行期间给出警告。如果信号和槽连接时包含了参数的名字,Qt 将会给出警告。以前我们列举的例子中都是控件的信号和槽。但是信号和槽机制在 QObject 中就实现了,可以实现在任何从 QObject 继承的子类中。class Employee:public QObjectQ_OBJECTpublic:Employee()mySalary=0;int salary()const return mySalary;public slots:void setSalary(int newSalary);signals:void salaryChanged(int newSalary);private:i
33、nt mySalary;void Employee:setSalary(int newSalary)if(newSalary!=mySalary)mySalary=newSalary;emit salaryChanged(mySalary);注意,只有 newSalary!=mySalary 时才发出 salary-Changed()信号,这样避免了死循环的出现。Qt 的 Meta-Object 系统Qt 的一个最主要的成功是对 C+扩展,即把彼此独立的软件模块连接起来,而不需要模块间的任何细节。这个机制就是Meta-Object系统,它提供了两个关键的用途:信号和槽和introspectio
34、n(内省)。introspection功能允许应用程序在运行时得到QObjec它子类的“meta-information”,这对实现信号和槽是很必要的,包括全部信号和槽的列表,和类的名字。这个机制还提供了属性(在 Qt Designer 中使用)和文本翻译(国际化)支持。它们构成了 QSA(Qt Script for Application)的基础。标准 C+不提供 Qt meta-object 系统需要的动态 meta-information。Qt 提供了一个独立的工具 moc,通过定义 Q_OBJECT 宏实现到 C+函数的转变。moc 是用纯 c+实现的,因此可以使用在任何 C+编译器中
35、。这个机制工作过程如下:Q_OBJECT 声明了一些 QObject 子类必须实现的内省函数:metaObject(),TR(),qt_metacall()等。Qt 的 moc 工具实现 Q_OBJECT 宏声明的函数和所有的信号。QObject 成员函数 connect()和 disconnect()使用这些内省函数实现信号和槽的连接。以上这些是通过 qmake,moc 和 QObject 自动处理的,程序员通常不用考虑它们。如果你感到对此好奇,可以查看 QMetaObject 类文档和 moc 实现的 c+代码。2.3 快速设计对话框(快速设计对话框(Rapid Dialog Design
36、)通常程序员们都是用 c+源代码编写 Qt 应用程序,Qt 也是很容易用来编写的。然而,许多程序员更喜欢用可视化的方法设计对话框,这样能更快速更容易对对话框进行修改。Qt Designer 满足了程序员的这一要求,提供了可视化设计对话框的方法。它可以给一个应用程序提供全部或者部分对话框。用 Qt Designer 设计的对话框和用 c+代码写成的对话框是一样的,可以用做一个常用的工具,并不对编辑器产生影响。在这一节中,我们使用 Qt Designer 创建 Go-to-Cell 对话框,无论用编写代码的方式还是用 Qt Designer,创建对话框都有如下基本的步骤:1、创建和初始化子控件。2
37、、把子控件放到布局管理器中。3、设置 tab 顺序。4、创建信号和槽。5、实现对话框的自己的槽函数。在 windows 平台 Qt 的安装目录的 bin 目录下,点击 desinger.exe,或者在 unix 平台,在命令行上输入 designer。当 Qt Designer 启动后,它会列出一个控件模板的列表,选择一个模板,进入设计。*原文中对 Qt Designer 的介绍略去不想翻译了,只要稍有点界面编程基础的都可以轻松使用。如果确实需要,以后再补上。我个人不喜欢使用这个东东,因为要多一个文件要维护,当然如果要频繁修改所设计的对话框,那这种方法还是很方便的。但不管怎么样,最终都要修改源
38、代码。所以我还是比较喜欢用源代码的方式把控件手工写出来。我想主要介绍把对话框设计好以后,保存为.ui 文件后的处理。*假如设计好的文件保存在 gotocell 目录中,命名为 gotocelldialog.ui 中,然后在同一个目录下创建一个 main.cpp 文件,编码如下:#include#include#include ui_gotocelldialog.hint main(int argc,char*argv)QApplication app(argc,argv);Ui:GoToCellDialog ui;QDialog*dialog=new QDialog;ui.setupUi(di
39、alog);dialog-show();return app.exec();保存后,在该目录下运行 qmake,创建.pro 文件,然后运行 qmake-project 生成 makefile 文件。qmake 可以发现 gotocelldialog.ui 文件,然后就会调用 uic(Qt 的用户界面编译器),uic 工具把 gotocelldialog.ui 转换成 c+代码,保存在 ui_gotocelldialog.h 中。在 ui_gotocelldialog.h 中,包含了 Ui:GoToCellDialog 类的定义,这个类和 gotocelldialog.ui 等价。这个类声明成
40、员变量存储对话框的子控件和布局管理器,setupUi()函数初始化对话框。这个类的定义看起来有点象下面这个样子:class Ui:GoToCellDialogpublic:QLabel*label;QLineEdit*lineEdit;QSpacerItem*spacerItem;QPushButton*okButton;QPushButton*cancelButton;.void setupUi(QWidget*widget).;这个类没有父类。使用时创建一个 QDialog,把它传递给 setupUi()函数。运行这个程序,对话框将会显示出来,但是有些功能它还不能实现:1、Ok 按钮是不可
41、用状态的2、Cancel 按钮不作任何事情3、编辑框除可以输入许可的字符或者数字外,还可以输入任何文本我们可以编写代码,让这个对话框变得有用起来。最直接的方法是创建一个新类,继承 QDialog 和 Ui:GoToCell-Dialog,补上缺少的功能。(这说明任何软件问题可以通过添加一层间接包装来简单解决)。通常命名新类规则是把去掉 uic 生成的类名去掉 Ui:前缀。创建 gotocelldialog.h 头文件,写下如下代码:#ifndef GOTOCELLDIALOG_H#define GOTOCELLDIALOG_H#include#include ui_gotocelldialog
42、.hclass GoToCellDialog:public QDialog,public Ui:GoToCellDialogQ_OBJECTpublic:GoToCellDialog(QWidget*parent=0);private slots:void on_lineEdit_textChanged();#endif新建 gotocelldialog.cpp 源文件,实现这个类:#include#include gotocelldialog.hGoToCellDialog:GoToCellDialog(QWidget*parent):QDialog(parent)setupUi(this)
43、;QRegExp regExp(A-Za-z1-90-90,2);lineEdit-setValidator(new QRegExpValidator(regExp,this);connect(okButton,SIGNAL(clicked(),this,SLOT(accept();connect(cancelButton,SIGNAL(clicked(),this,SLOT(reject();void GoToCellDialog:on_lineEdit_textChanged()okButton-setEnabled(lineEdit-hasAcceptableInput();在构造函数中
44、,我们调用 setupUi()初始化这个对话框。由于多继承,我们可以直接使 Ui:GoToCellDialog 的成员。创建了用户界面以后,我们可以把子控件的信号和槽函数连接起来。在构造函数中,我们还创建一个许可器(validator)限制编辑框输入的范围。Qt 提供了三个许可器类:QIntValidator,QDoubleValidator 和QRegExpValidator。这里我们使用了 QRegExpValidator,使用的表达式为“A-Za-z1-90-90,2”这个表达式的意思是第一个字符输入为大写或者小写字母,第二个字符为一个数字范围是 1 到 9,第三个字符是一个数字范围为
45、0 到 9。在 QRegExpValidator 的构造函数中,第二个参数为 this,把当前类作为它的父控件,这样就可以不用删除它,父控件析构时可以被自动删除。Qt 的父子机制在 QObject 中实现的。当我们创建一个带有父的对象(如一个子控件,一个许可器,布局管理器等)时,父对象把子对象放到自己的子对象列表中。父对象被删除时,它查找自己的子对象并把每一个删除掉。这些子对象再把自己的子对象删除掉,如此递归,知道删除所有对象。这种父子对象的机制简化了内存管理,减少了内存泄漏的危险。需要程序员删除的对象就是我们使用 new 创建的没有父对象的对象。如果我们在父对象存在时删除了它的一个子对象,Q
46、t 将会在父列表中自动删除。(需要记住的是 Qt 只是删除有父的对象,父对象还是需要手动删除的,还有就是那些用new 申请的没有指定父的内存,一般情况下,在对话框里的子控件,许可器和布局管理器由 Qt 自己管理,其他还要程序员小心删除)对于控件来讲,父对象还有一个意义:子控件在父对象的显示区域内显示。当父控件删除后,子控件不但在内存中被删除,它也同时在屏幕上消失。在构造函数的最后两行,把 QDialog 的 accept()函数连接到 OK 按钮的点击信号,把 Cancel 按钮的点击信号连接到 reject()函数。这两个槽函数都关闭这个对话框,但是 accept()返回 QDialog:A
47、ccepted(值为 1),reject()返回值为 QDialog:Rejected(值为 0)。不同的返回值可以判断用户点击了那个按钮。on_lineEdit_textChanged()槽函数控制 Ok 按钮的可用状态,通过编辑框中的输入字符,如果字符有效 Ok 按钮则有效,否则为不可用状态。QLineEdit:hasAcceptableInput()根据我们在构造函数中设置的许可器返回 bool 值。这就完成了这个对话框,现在重写这个 main.cpp 文件:#include#include gotocelldialog.hint main(int argc,char*argv)QApp
48、lication app(argc,argv);GoToCellDialog*dialog=new GoToCellDialog;dialog-show();return app.exec();编译这个程序(qmake-project;qmake gotocell.pro)然后运行。输入“A12”,Ok 按钮变为可用。试着输入一行随意字符,观察许可器的反映。点击 Cancel 按钮关闭这个对话框。使用 qt Designer 可以不改变源程序的情况下改变对话框的设计。如果对话框用 C+代码编写,改变它将会很费力的。使用 Qt Designer,uic 自动重新生成源文件。不会浪费任何时间。2.
49、4 能够改变的对话框能够改变的对话框(Shape-Changing Dialogs)前面几章我们设计的对话框都是不能改变它的样子的。但是有时需要对话框根据要求进行适当的改变。两个最常用的需要改变的对话框是可扩展对话框和多页对话框。这两种类型的可以通过代码编写,也可以用 Qt Designer 设计。可扩展对话框通常外观简单,带有一个可扩展按钮来切换对话框的简单外观和可扩展外观。这种对话框通常为了迎合普通用户和高端用户而设计的,如果没有特别请求隐藏高级应用部分。在这一节,我们使用 Qt Designer 设计一个可扩展对话框。对话框是一个表格程序的排序对话框,对用户选择的一些列按要求排列。对话框
50、的简单外观允许用户输入一个简单排序关键词,扩展部分允许输入两个额外的排序关键词。一个 More 按钮使用户在简单外观和扩展外观进行切换。我们使用 Qt Designer 创建这个可扩展的对话框,在运行时刻隐藏高级功能,这个看起来很复杂的对话框用 Qt Designer 可以很容易实现。首先设计好第一个关键词,第二个和第三个关键词通过复制就可以得到:1、启动 File|New 菜单,选择“Dialog with Buttons Right”模板。2、创建 More 按钮,并将它托到右边的垂直布局管理器中,放到垂直空白的下面。设置按钮的文本属为“&More”,它的 checkable 属性为“tr