/

/

Qt 学习之路 2(14):对话框数据传递

Qt 学习之路 2(14):对话框数据传递

 豆子  2012年9月15日  Qt 学习之路 2  53条评论

对话框的出现用于完成一个简单的或者是短期的任务。对话框与主窗口之间的数据交互相当重要。本节将讲解如何在对话框和主窗口之间进行数据交互。按照前文的讲解,对话框分为模态和非模态两种。我们也将以这两种为例,分别进行阐述。

模态对话框使用了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()函数判断是不是该对话框,然后从映射表中将其删除)。

最新文章

  1. Python12期培训班-day1-登陆验证代码分享
  2. Ext.NET 4.1.0 搭建页面布局
  3. 如何从oc中去获取一个私有的变量.....
  4. 【PL/SQL练习】函数
  5. Entity Framework公共的增删改方法
  6. 两个队列+k叉哈夫曼树 HDU 5884
  7. bootstrap easyUI 的选型
  8. ORACLE数据库常用查询二
  9. poj 2393 Yogurt factory(dp+贪心)
  10. MySQL 1054错误 Unknown column .... in &#39;on clause&#39;
  11. Collections类解析
  12. H5_0004:JS设置循环debugger的方法
  13. Ruby版快速排序
  14. [转]git 删除远程仓库文件
  15. 创建Java多线程的两种方式和线程异常
  16. 【整理】HTML5游戏开发学习笔记(3)- 抛物线运动
  17. PL/SQL的下载与安装
  18. oracle数据库表空间的创建与使用
  19. [Oracle]Oracle良性SQL建议
  20. JAVA加密算法(DSA)

热门文章

  1. java 多线程系列基础篇(八)之join()、start()、run()方法
  2. 北京儿研所自制药一览表,宝妈们必读!&lt;转&gt;
  3. IDEA中Git实战
  4. MySQL存储引擎 -- MyISAM 与 InnoDB 理论对比
  5. Lucene源码解析--Analyzer之Tokenizer
  6. C++ 私有构造函数的作用
  7. Halcon从某一个图片以指定区域绘制到另一个图像
  8. 算法Sedgewick第四版-第1章基础-1.4 Analysis of Algorithms-003定理
  9. vue 之 计算属性和侦听器
  10. C#中 ACCESS数据库常用操作语句...容易出错的地方(DateTime类型)