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 内置的一系列对话框,用于简化开发.事实上, ...
 
随机推荐
- 使用pip一次升级所有安装的Python包(太牛了)
			
import pip from subprocess import call for dist in pip.get_installed_distributions(): call("pip ...
 - DAY7-面向对象之封装
			
一.引子 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,还有alex一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装=‘隐藏’,这种理解是相当片面的 二.先看如何隐藏 在 ...
 - Spring装配各种类型bean
			
一.单属性值的装配 //setter注入,提供无参构造器,提供setXX方法 <property name="" value=""></pro ...
 - [Python Study Notes]堆叠柱状图绘制
			
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ...
 - nginx配置域名
			
其他都一样,就特别说下server块的配置. server { listen 80; server_name www.icweshop.com; # 注意:这里你填写的域名必须在/etc/hosts中 ...
 - go语言linux环境配置
			
linux的设置方法:有4个环境变量需要设置:GOROOT.GOPATH.GOBIN以及PATH.需要设置到某一个profile文件中(~/.bash_profile(单一用户)或/etc/profi ...
 - JS Number类型数字位数及IEEE754标准
			
JS的基础类型Number,遵循 IEEE 754 规范,采用双精度存储(double precision),占用 64 bit.如图 意义 1位用来表示符号位 11位用来表示指数 52位表示尾数 浮 ...
 - [转载]HTTP的无状态是什么意思?
			
文章地址:https://www.cnblogs.com/bellkosmos/p/5237146.html#commentform 作者:赛艇队长 引子: 最近在好好了解http,发现对介绍http ...
 - Inheritance with EF Code First: Part 3 – Table per Concrete Type (TPC)
			
Inheritance with EF Code First: Part 3 – Table per Concrete Type (TPC) This is the third (and last) ...
 - JavaWeb_增强for循环
			
引入增强for循环的原因:在JDK5以前的版本中,遍历数组或集合中的元素,需要先获得数组的长度或集合的迭代器,比较麻烦. JDK5中定义了一种新的语法----增强for循环,以简化此类操作.增强for ...