Qt 学习之路 2(14):对话框数据传递
Qt 学习之路 2(14):对话框数据传递
对话框的出现用于完成一个简单的或者是短期的任务。对话框与主窗口之间的数据交互相当重要。本节将讲解如何在对话框和主窗口之间进行数据交互。按照前文的讲解,对话框分为模态和非模态两种。我们也将以这两种为例,分别进行阐述。
模态对话框使用了exec()函数将其显示出来。exec()函数的真正含义是开启一个新的事件循环(我们会在后面的章节中详细介绍有关事件的概念)。所谓事件循环,可以理解成一个无限循环。Qt 在开启了事件循环之后,系统发出的各种事件才能够被程序监听到。这个事件循环相当于一种轮询的作用。既然是无限循环,当然在开启了事件循环的地方,代码就会被阻塞,后面的语句也就不会被执行到。因此,对于使用了exec()显示的模态对话框,我们可以在exec()函数之后直接从对话框的对象获取到数据值。
看一下下面的代码:
|
1
2
3
4
5
6
7
|
void MainWindow::open()
{
QDialog dialog(this);
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
qDebug() << dialog.result();
}
|
上面的代码中,我们使用exec()显示一个模态对话框。最后一行代码,qDebug()类似于std::cout或者 Java 的System.out.println();语句,将后面的信息输出到标准输出,一般就是控制台。使用qDebug()需要引入头文件。在exec()函数之后,我们直接可以获取到 dialog 的数据值。注意,exec()开始了一个事件循环,代码被阻塞到这里。由于exec()函数没有返回,因此下面的result()函数也就不会被执行。直到对话框关闭,exec()函数返回,此时,我们就可以取得对话框的数据。
需要注意的一点是,如果我们设置 dialog 的属性为WA_DeleteOnClose,那么当对话框关闭时,对象被销毁,我们就不能使用这种办法获取数据了。在这种情况下,我们可以考虑使用 parent 指针的方式构建对话框,避免设置WA_DeleteOnClose属性;或者是利用另外的方式。
实际上,QDialog::exec()是有返回值的,其返回值是QDialog::Accepted或者QDialog::Rejected。一般我们会使用类似下面的代码:
|
1
2
3
4
5
6
|
QDialog dialog(this);
if (dialog.exec() == QDialog::Accepted) {
// do something
} else {
// do something else
}
|
来判断对话框的返回值,也就是用户是点击了“确定”还是“取消”。更多细节请参考QDialog文档。
模态对话框相对简单,如果是非模态对话框,QDialog::show()函数会立即返回,如果我们也这么写,就不可能取得用户输入的数据。因为show()函数不会阻塞主线程,show()立即返回,用户还没有来得及输入,就要执行后面的代码,当然是不会有正确结果的。那么我们就应该换一种思路获取数据,那就是使用信号槽机制。
由于非模态对话框在关闭时可以调用QDialog::accept()或者QDialog::reject()或者更通用的QDialog::done()函数,所以我们可以在这里发出信号。另外,如果找不到合适的信号发出点,我们可以重写QDialog::closeEvent()函数,在这里发出信号。在需要接收数据的窗口(这里是主窗口)连接到这个信号即可。类似的代码片段如下所示:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//!!! Qt 5
// in dialog:
void UserAgeDialog::accept()
{
emit userAgeChanged(newAge); // newAge is an int
QDialog::accept();
}
// in main window:
void MainWindow::showUserAgeDialog()
{
UserAgeDialog *dialog = new UserAgeDialog(this);
connect(dialog, &UserAgeDialog::userAgeChanged, this, &MainWindow::setUserAge);
dialog->show();
}
// ...
void MainWindow::setUserAge(int age)
{
userAge = age;
}
|
上面的代码很简单,这里不再赘述。另外,上述代码的 Qt 4 版本也应该可以很容易地实现。
不要担心如果对话框关闭,是不是还能获取到数据。因为 Qt 信号槽的机制保证,在槽函数在调用的时候,我们始终可以使用sender()函数获取到 signal 的发出者。关于sender()函数,可以在文档中找到更多的介绍。顺便说一句,sender()函数的存在使我们可以利用这个函数,来实现一个只能打开一个的非模态对话框(方法就是在对话框打开时在一个对话框映射表中记录下标记,在对话框关闭时利用sender()函数判断是不是该对话框,然后从映射表中将其删除)。
Qt 学习之路 2(14):对话框数据传递的更多相关文章
- QT学习之路--创建一个对话框
Q_OBJECT:这是一个宏,凡是定义信号槽的类都必须声明这个宏. 函数tr()全名是QObject::tr(),被他处理过的字符串可以使用工具提取出来翻译成其他语言,也就是做国际化使用. 对于QT学 ...
- Qt 学习之路 :可视化显示数据库数据
前面我们用了两个章节介绍了 Qt 提供的两种操作数据库的方法.显然,使用QSqlQuery的方式更灵活,功能更强大,而使用QSqlTableModel则更简单,更方便与 model/view 结合使用 ...
- Qt学习之路(54): 自定义拖放数据对象
前面的例子都是使用的系统提供的拖放对象 QMimeData 进行拖放数据的存储,比如使用 QMimeData::setText() 创建文本,使用 QMimeData::urls() 创建 URL 对 ...
- Arm开发板+Qt学习之路-析构函数和对话框一起时
先记录一下代码 一:先将指针释放掉,在显示对话框 void MainWindow::canResponseError(SendCanMsgThread *sendCanMsgThread ){ std ...
- Qt 学习之路 2(40):隐式数据共享
Qt 学习之路 2(40):隐式数据共享 豆子 2013年1月21日 Qt 学习之路 2 14条评论 Qt 中许多 C++ 类使用了隐式数据共享技术,来最大化资源利用率和最小化拷贝时的资源消耗.当作为 ...
- Qt 学习之路 2(57):可视化显示数据库数据
Qt 学习之路 2(57):可视化显示数据库数据(skip) 豆子 2013年6月26日 Qt 学习之路 2 26条评论 前面我们用了两个章节介绍了 Qt 提供的两种操作数据库的方法.显然,使用QSq ...
- Qt 学习之路 2(53):自定义拖放数据
Qt 学习之路 2(53):自定义拖放数据 豆子 2013年5月26日 Qt 学习之路 2 13条评论上一章中,我们的例子使用系统提供的拖放对象QMimeData进行拖放数据的存储.比如使用QM ...
- Qt 学习之路 2(17):文件对话框
Home / Qt 学习之路 2 / Qt 学习之路 2(17):文件对话框 Qt 学习之路 2(17):文件对话框 豆子 2012年9月24日 Qt 学习之路 2 85条评论 在前面的章节中 ...
- Qt 学习之路 2(15):标准对话框 QMessageBox
Qt 学习之路 2(15):标准对话框 QMessageBox 豆子 2012年9月18日 Qt 学习之路 2 40条评论 所谓标准对话框,是 Qt 内置的一系列对话框,用于简化开发.事实上, ...
随机推荐
- 【转载】你知道 Linux 内核是如何构建的吗?
内核的根 Makefile 负责构建两个主要的文件:vmlinux (内核镜像可执行文件)和模块文件.内核的 Makefile 从定义如下变量开始: VERSION = PATCHLEVEL = SU ...
- DAY10-MYSQL完整性约束
一 介绍 约束条件与数据类型的宽度一样,都是可选参数 作用:用于保证数据的完整性和一致性主要分为: PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录 FOREIGN KEY ...
- Activity的显式跳转和隐式挑战
安卓中Activity的跳转几乎是每一个APP都会用到的技术点.而且他的使用时十分简单的. 这里我们先说一下主要的技术要点: 1.在清单文件中注册新的Activity 2.通过意图跳转 这里我们看一下 ...
- cf688B-Lovely Palindromes
http://codeforces.com/problemset/problem/688/B B. Lovely Palindromes time limit per test 1 second me ...
- linux安装thrift
安装配置Thrift Thrift的编译器使用C++编写的,在安装编译器之前,首先应该保证操作系统基本环境支持C++的编译,安装相关依赖的软件包,如下所示 sudo yum install autom ...
- java中public static void main(String[] args)中String[] args代表什么意思?
这是java程序的入口地址,java虚拟机运行程序的时候首先找的就是main方法.跟C语言里面的main()函数的作用是一样的.只有有main()方法的java程序才能够被java虚拟机欲行,可理解为 ...
- R: 自动计算代码运行时间
################################################### 问题:代码运行时间 18.4.25 怎么计算代码的运行时间? 解决方案: ptm = pro ...
- Socket编程--基础(基本server/client实现)
IPv4套接口地址结构 IPv4套接口地址结构通常也称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件中 LINUX结构下的常用结构,一般创建套接字的时候都要将这个结构里面的 ...
- UVa 766 Sum of powers (伯努利数)
题意: 求 ,要求M尽量小. 析:这其实就是一个伯努利数,伯努利数公式如下: 伯努利数满足条件B0 = 1,并且 也有 几乎就是本题,然后只要把 n 换成 n-1,然后后面就一样了,然后最后再加上一个 ...
- C++中四种强制类型转换区别详解
C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 1.转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非const对 ...