第二章 创建对话框

1、子类化QDialog

第一个例子是完全使用C++编写的Find对话框。

finddialog.h:

 1 #ifndef FINDDIALOG_H
 2 #define FINDDIALOG_H
 3
 4 #include <QDialog>
 5
 6 class QCheckBox;
 7 class QLabel;
 8 class QLineEdit;
 9 class QPushButton;
10
11 class FindDialog : public QDialog
12 {
13     Q_OBJECT
14 public:
15     FindDialog(QWidget *parent = 0);
16 signals:
17     void findNext(const QString &str, Qt::CaseSensitivity cs);
18     void findPrevious(const QString &str, Qt::CaseSensitivity cs);
19 private slots:
20     void findClicked();
21     void enableFindButton(const QString &text);
22 private:
23     QLabel *label;
24     QLineEdit *lineEdit;
25     QCheckBox *caseCheckBox;
26     QCheckBox *backwardCheckBox;
27     QPushButton *findButton;
28     QPushButton *closeButton;
29 };
30
31 #endif // FINDDIALOG_H

头部的预编译指令是为了防止对这个头文件的多重包含

对于定义了信号与槽的类来说在类定义的开始处的Q_OBJECT宏都是必须的,它给出了一些函数的声明

FindDialog类的构造函数是典型的Qt窗口部件类的定义方式。parent参数指定了它的父窗口部件。该参数的默认值是一个空指针,意味着该对话框没有父对象。

signals关键字实际上是一个宏,C++预处理器会在编译程序找到它之前把它转换成标准C++代码。我的疑问是为什么槽的声明是私有的。

finddialog.cpp:

 1 #include <QtGui>
 2 #include <QLabel>
 3 #include <QCheckBox>
 4 #include <QLineEdit>
 5 #include <QPushButton>
 6 #include <QHBoxLayout>
 7 #include <QVBoxLayout>
 8 #include "finddialog.h"
 9
10 FindDialog::FindDialog(QWidget *parent)
11     :QDialog(parent)
12 {
13     label = new QLabel(tr("Find &what:"));
14     lineEdit = new QLineEdit;
15     label->setBuddy(lineEdit);
16
17     caseCheckBox = new QCheckBox(tr("Match &case"));
18     backwardCheckBox = new QCheckBox(tr("Search &backward"));
19
20     findButton = new QPushButton(tr("&Find"));
21     findButton->setDefault(true);
22     findButton->setEnabled(false);
23
24     closeButton = new QPushButton("Close");
25     connect(lineEdit, SIGNAL(textChanged(const QString &)),
26             this, SLOT(enableFindButton(const QString &)));
27     connect(findButton, SIGNAL(clicked()),
28             this, SLOT(findClicked()));
29     connect(closeButton, SIGNAL(clicked()),
30             this, SLOT(close()));
31
32     QHBoxLayout *topLeftLayout = new QHBoxLayout;
33     topLeftLayout->addWidget(label);
34     topLeftLayout->addWidget(lineEdit);
35
36     QVBoxLayout *leftLayout = new QVBoxLayout;
37     leftLayout->addLayout(topLeftLayout);
38     leftLayout->addWidget(caseCheckBox);
39     leftLayout->addWidget(backwardCheckBox);
40
41     QVBoxLayout *rightLayout = new QVBoxLayout;
42     rightLayout->addWidget(findButton);
43     rightLayout->addWidget(closeButton);
44     rightLayout->addStretch();
45
46     QHBoxLayout *mainLayout = new QHBoxLayout;
47     mainLayout->addLayout(leftLayout);
48     mainLayout->addLayout(rightLayout);
49     setLayout(mainLayout);
50
51     setWindowTitle(tr("Find"));
52     setFixedHeight(sizeHint().height());
53 }
54
55 void FindDialog::findClicked()
56 {
57     QString text = lineEdit->text();
58     Qt::CaseSensitivity cs =
59             caseCheckBox->isChecked() ? Qt::CaseSensitive
60                                       : Qt::CaseInsensitive;
61     if(backwardCheckBox->isChecked())
62     {
63         emit findPrevious(text, cs);
64     }
65     else
66     {
67         emit findNext(text, cs);
68     }
69 }
70
71 void FindDialog::enableFindButton(const QString &text)
72 {
73     findButton->setEnabled(!text.isEmpty());
74 }

在字符串周围的tr函数调用时把它们翻译成其他语言的标记,即使现在没有需要将程序翻译成其它语言,但是这样做也是有好处的。

在部件的text字符创中使用了符号“&”表示快捷键,使用alt+“&”后的第一个字母可以实现快捷的选中该部件。

所谓buddy,就是一个窗口部件,它可以再按下标签的快捷键时接受焦点输入。

setDefault让Find按钮称为默认按钮,默认按钮即当用户按下回车时能够按下对应的键。

omit是Qt中的关键字,它会被C++预处理器转换成标准C++代码。

main.cpp:

 1 #include <QApplication>
 2 #include "finddialog.h"
 3
 4 int main(int argc, char** argv)
 5 {
 6     QApplication app(argc, argv);
 7     FindDialog *dialog = new FindDialog;
 8     dialog->show();
 9     return app.exec();
10 }

运行效果:

2、深入介绍槽与信号

信号与槽是Qt编程的基础。它可以让编程人员将这些互不了解的对象绑定在一起。

槽和普通的C++函数几乎是一样的,可以使虚函数、可以被重载、可以使公有的、保护的、私有的。并且也可以被其他C++成员函数直接调用,还有它们的参数可以使任意类型,唯一不同的是:槽还可以和信号连接在一起,在这种情况下,每当发射这个信号的时候,就会自动调用这个槽。

connect(sender, SIGNAL(signal), receiver,SLOT(slot));

这里的sender和receiver是指向QObject的指针,signal和slot是不带参数的函数名。实际上,SIGNAL和SLOT宏会把它们的参数转换成相应的字符串。

  • 一个信号可以连接多个槽

在发射这个信号的时候会以不确定的顺序一个接一个的调用这些槽

  • 多个信号可以连接同一个槽

无论发射哪一个信号都会调用这个槽

  • 一个信号可以与另外一个信号连接

当发射第一个信号的时候也会发射第二个信号

  • 连接可以被移除

这种情况很少用

注意:要把信号连接到槽,它们的参数必须具有相同的顺序和相同的类型。例外:如果信号比连接的槽的参数多,那么后面多余的参数将被忽略。

3、快速设计对话框

这一节会使用Qt Designer来可视化的设计一个对话框。

操作步骤就是使用Qt Designer来设计需要的对话框,然后保存为.ui的格式。

在编译的时候会将.ui格式的文件转换为C++并且存储在ui_name.h和ui_name.cpp中。

生成的类没有任何基类,当在程序中使用它时,可以创建一个QDialog类的对象,然后把它传递给setupUi()函数。

现在定义一个新的类继承自QDialog和Ui::GoToCellDialog类(我填写的Ui文件生成的类名)。

gotocelldialog.h:

 1 #ifndef GOTOCELLDIALOG_H
 2 #define GOTOCELLDIALOG_H
 3
 4 #include <QDialog>
 5 #include "ui_gocelldialog.h"
 6
 7 class GotoCellDialog : public QDialog, public Ui::GoToCellDialog
 8 {
 9     Q_OBJECT
10 public:
11     GotoCellDialog(QWidget *parent = 0);
12 private slots:
13     void on_lineEdit_textChanged();
14 };
15
16 #endif // GOTOCELLDIALOG_H

该类继承自两个类:QDialog、Ui::GoToCellDialog

gotocelldialog.cpp:

 1 #include <QtGui>
 2 #include "gotocelldialog.h"
 3
 4 GotoCellDialog::GotoCellDialog(QWidget *parent)
 5     : QDialog(parent)
 6 {
 7     setupUi(this);
 8
 9     // QRegExp regExp("[A-Za-z][1-9][0-9]{0, 2}");
10     QRegExp regExp("[A-Za-z][1-9][0-9]{0,2}");
11     lineEdit->setValidator(new QRegExpValidator(regExp, this));
12
13     connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
14     connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
15 }
16
17 void GotoCellDialog::on_lineEdit_textChanged()
18 {
19     okButton->setEnabled(lineEdit->hasAcceptableInput());
20 }

实现文件中绑定了需要绑定的信号与槽。

对编辑框的输入进行了验证,使用正则表达式的方法来验证。

accept()槽可以讲对话框返回的结果变量设置为QDialog::Accepted,其值为1、而reject()槽会把对话框的值设置为QDialog::Rejected,其值为0。可以根据对话框的返回值来判断是否点击了OK按钮。

main.cpp:

 1 #include <QApplication>
 2
 3 #include "gotocelldialog.h"
 4
 5 int main(int argc, char *argv[])
 6 {
 7     QApplication a(argc, argv);
 8
 9     GotoCellDialog *dialog = new GotoCellDialog;
10     dialog->show();
11
12     return a.exec();
13 }

实例化一个该类的对象并显示出来。

使用QDialogButtonBox来制作这个对话框,以使它在MAC平台上显得更加圆润。

4、

第二章 创建对话框

时间: 2024-10-20 13:43:30

第二章 创建对话框的相关文章

[Effective Java 读书笔记] 第二章 创建和销毁对象 第一条

第二章  创建和销毁对象 第一条 使用静态工厂方法替代构造器,原因: 静态工厂方法可以有不同的名字,也就是说,构造器只能通过参数的不同来区分不同的目的,静态工厂在名字上就能表达不同的目的 静态工厂方法不用每次调用的时候都创建新的对象(其实是因为它是static的,所以只能用static的,所以是一早就创建了,不需要重复创建吧..),比如书中 Boolean.valueOf(boolean) 1 public static final Boolean TRUE = new Boolean(true

[Effective Java]第二章 创建和销毁对象

第一章      前言 略... 第二章      创建和销毁对象 1.            考虑用静态工厂方法代替构造器 创建对象方法:一是最常用的公有构造器,二是静态工厂方法.下面是一个Boolean的简单示例: public static Boolean valueOf(boolean b) { return (b ? Boolean.TRUE : Boolean.FALSE); } l  静态工厂方法与构造器不同的第一大优势在于,它们有名称. 作用不同的公有构造器只能通过参数来区别(因

Effective java 第二章创建和销毁对象 读书笔记

建和销毁对象 一般有两种方式,一种是获得本身的实例,最常用的方法就是提供一个共有的构造器.第二个方法是,类可以提供一个共有的静态工厂方法. 静态工厂方法与构造器不同的三大优势: 有名字: 调用时不用创建新的对象: 返回原来类型的任何子类型对象. 第四大优势: 在创建参数化类型实例的时候,它们使代码变得更加简洁. 服务提供者框架 三个组件: 服务接口 提供者主持API 服务访问API 可选: 服务提供者接口 静态工厂方法的缺点: 类如果不含共有的或者受保护的构造器,就不能被子类化: 它们与其他的静

评论设置----第二章:创建和管理内容

点击“保存并继续出版”按钮. Drupal将保存的内容项,现在该项目将 出现在主导航菜单上,用按字母顺序排列的菜单项.缺省情况下,菜单项 按字母顺序排序;你可以通过菜单管理工具更改排序顺序哪些 在第8章中讨论在这种情况下,我们是一个单件的内容链接到菜单项.在案件 要在其中多个内容项目链接到一个菜单项,你需要创建一个登陆页面(见 第7章)或视图(参见第10章).如果您使用的是标准Bartik主题(这是默认的主题 在Drupal 8),你应该看到靠近你的页面的顶部,您在“菜单中输入的值的新选项卡 链

URL路径设置----第二章:创建和管理内容

形式立即显示内容的下面.编辑内容,然后选择关闭选项,并点击 “保存并继续出版”按钮.你会发现在如何显示您的内容项的显著变化, 因为评论将不再出现. 图2-15.随着打开的默认设置,用户现在可以发布在网站上的评论 随着打开的默认设置,游客到您的网站现在可以编写和响应发表评论 你的内容项(假设你已经设置权限允许匿名用户发表评论, 我将在第6章盖).请尝试输入主题和注释,然后点击保存.你的评论 现在应该出现在注释部分. 由于内容作者(或该网站的管理员),你可以删除,编辑或回复评论 点击每个注释下的链接

预览和全展示----第二章:创建和管理内容

默认情况下,Drupal允许的内容项进行编辑,更新和删除该项目的作者.只有网站 这允许他们管理员或用户与角色进行编辑,更新和删除其他作者的内容可以 更改您的内容.如果您没有看到旁边的编辑内容项目的标题,那么你就不是 登录与适当的权限的帐户进行修改,该项目. 要更改内容项,单击编辑选项卡. Drupal将在编辑模式下显示的内容项, 在这里你可以更改或删除的项(见图2-6). 图2-6.内容将显示在编辑模式 还有另一种方式来编辑您的文章.尝试更新您在上一步中创建的文章 导航回主页.要导航回主页,点击

第二章 创建、删除和修改表

创建表 create table 表名(属性名 数据类型 [完整性约束条件], 属性名 数据类型 [完整性约束条件], 属性名 数据类型 [完整性约束条件]): 注:建表前先选择数据库 约束条件 约束条件 说明 primary key 设为主键 foreign key 设为外键,是与之联系的某表的主键 not null 设该属性不能为空 unique 标识该属性的值是唯一的 auto_increment 标识该属性的值自动增加 default 设置该属性的默认值 查看表结构 describe 表

其它内容选项----第二章:创建和管理内容

一个弹出式窗口将出现在其中您可以更新文本不留主页 (见图2-8).修改编辑器中的文本,然后单击保存按钮.新版本 您保存后的网页上会自动出现.这是执行快速文本的好方法 触摸起坐,你已经发现了或固定的错误. 图2-8.对网页内容编辑 如果进行一些修改,喜欢全屏幕编辑器界面中,单击铅笔图标(见 图2-7),然后选择编辑选项.这是因为点击任何内容项的标题来查看同一 内容详细页(即内容项目作为一个独立的页面的完整渲染),然后选择编辑选项卡 内容的标题下方,就像我们以前一样. 其它内容选项 在内容编辑表格的

一起读读libevent的源代码:Libevent 第二章 创建Event base (1)

在您可以使用任何有趣的libevent函数,需要分配一个或多个event_base结构.每个event_base结构持有一组事件,可以poll决定哪些事件是激活的. 如果一个event_base设置使用lock,可以访问多个线程之间.然而,它的循环只能在单个线程中运行.如果你想有多个线程轮询IO,你需要为每个线程一个event_base. 支持一下的方法来进行决定哪个是激活的: select poll epoll kqueue devpoll evport win32 用户可以禁用特定的后端(上