【Qt笔记】对话框数据传递

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

 

模态对话框使用了exec()函数将其显示出来。exec()函数的真正含义是开启一个新的事件循环(咱们会在后面的章节中详细介绍有关事件的概念)。所谓事件循环,能够理解成一个无限循环。Qt 在开启了事件循环以后,系统发出的各类事件才可以被程序监听到。这个事件循环至关于一种轮询的做用。既然是无限循环,固然在开启了事件循环的地方,代码就会被阻塞,后面的语句也就不会被执行到。所以,对于使用了exec()显示的模态对话框,咱们能够在exec()函数以后直接从对话框的对象获取到数据值。this

看一下下面的代码:线程

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属性;或者是利用另外的方式。code

实际上,QDialog::exec()是有返回值的,其返回值是QDialog::Accepted或者QDialog::Rejected。通常咱们会使用相似下面的代码:对象

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()函数,在这里发出信号。在须要接收数据的窗口(这里是主窗口)链接到这个信号便可。相似的代码片断以下所示:it

//!!! 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 信号槽的机制保证,在槽函数在调用的时候,咱们始终可使用sender()函数获取到 signal 的发出者。关于sender()函数,能够在文档中找到更多的介绍。顺便说一句,sender()函数的存在使咱们能够利用这个函数,来实现一个只能打开一个的非模态对话框(方法就是在对话框打开时在一个对话框映射表中记录下标记,在对话框关闭时利用sender()函数判断是否是该对话框,而后从映射表中将其删除)。class

相关文章
相关标签/搜索