博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Qt学习五 - 对话框
阅读量:6884 次
发布时间:2019-06-27

本文共 5305 字,大约阅读时间需要 17 分钟。

一、对话框简介

开发桌面程序,总会需要使用对话框来实现短期任务或者简洁的交互。在Qt中,提供了QDialog类来实现对话框。在QDialog和其子类中,对parent指针有额外的解释:当parent为NULL时,对话框会作为一个顶层窗口,否则则会作为其父组件的子对话框(此时默认显示在父组件的中心位置)。可以新建一个项目,在主窗口上添加一个push button,然后在相应的槽函数中添加如下代码:

QDialog dlg;    dlg.setWindowTitle("hello dialog !");    dlg.exec();

运行程序查看效果,然后将其修改为:

QDialog dlg(this);    dlg.setWindowTitle("hello dialog !");    dlg.exec();

再运行程序,对比两次的差别。

对话框分为模态对话框和非模态对话框两种。模态对话框又分为应用级别的模态对话框和窗口级别的模态对话框。应用级别的模态对话框会阻塞同一应用下的所有窗口,当对话框出现时,用户先要和对话框进行交互,直到对话框关闭才可以和访问其他窗口;窗口级别的模态对话框只会阻塞与对话框相关联的窗口,允许用户与其他窗口进行交互;非模态对话框则与模态对话框相反,它不会阻塞用户与任何窗口的交互。

Qt中,实现应用级别的模态对话框使用QDialog::exec()函数,例如我们上面写的代码,实现窗口级别的模态对话框使用QDialog::open()函数,实现非模态对话框使用QDialog::show()函数。将上面的代码改为非模态对话框方式:

QDialog dlg;    dlg.setWindowTitle("hello dialog !");    dlg.show();

运行发现对话框一闪而过,这是因为对话框创建在栈上,并且show()函数不会阻塞当前线程,对话框显示后代码会继续向下执行,当执行完按钮的槽函数后,超出对话框的作用域,对话框就被析构了。所以需要将对话框创建在堆上,如下:

QDialog* dlg = new QDialog;    dlg->setWindowTitle("hello dialog !");    dlg->show();

创建在堆上就会涉及到释放内存,我们可以指定对话框的parent 为主窗口

QDialog* dlg = new QDialog(this);

但是这样如果主窗口不关闭,dialog就不会被销毁,内存会一直被占用。并且QWidget类的parent只能是QWidget的指针,如果对话框不是显示在界面类上怎么办?针对这个问题,我们可以设置QDialog的WindowAttribute

QDialog* dlg = new QDialog;    dlg->setWindowTitle("hello dialog !");    dlg->setAttribute(Qt::WA_DeleteOnClose);    dlg->show();

这样当对话框关闭时会自动销毁,QObject类还有一个deleteLater()函数,该函数会在事件循环结束后销毁该对话框。

二、对话框数据传递

从模态对话框获取数据:

QDialog dlg;    dlg.exec();    qDebug() << dlg.result();

运行后,不会获取到结果,这是因为exec()(开启一个事件循环)会阻塞当前线程,当关闭对话框exec()函数返回时才会执行下面的代码,才可以获取到数据。如果设置了WA_DeleteOnClose,那么当对话框关闭时就会被销毁,就不能用这种方法获取数据了。exec()函数有两个返回值:QDialog::Accepted和QDialog::Rejected,通常我们会使用类似下面的代码:

QDialog dlg;    if (dlg.exec() == QDialog::Accepted)    {        //do something    }    else    {        //do something    }

从非模态对话框获取数据:

因为QDialog::show()函数不会阻塞线程,show()会立即返回,所以不能通过上面的方式来获取数据,否则不等用户输入,已经执行了下面的代码。我们可以使用信号和槽机制,来获取数据。非模态对话框在关闭时可以调用QDialog::accept()或者QDialog::reject或者QDialog::done()函数,所以我们可以重写QDialog::accept()函数,在这里发送信号。也可以重写QDialog::closeEvent()函数来发送信号。然后在需要接受数据的窗口链接这个信号即可。

在QDialog子类中:

void UserAgeDialog::accept()    {        emit userAgeChanged(newAge); // newAge is an int        QDialog::accept();    }

在mainwindow中:

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内置的对话框,它们都是继承与QDialog类。打开帮助文档找到QDialog类,

可以看到当前版本Qt所支持的内置对话框。

  • QColorDialog:选择颜色
  • QErrorMessage:错误提示
  • QFileDialog:选择文件
  • QFontDialog:选择字体
  • QinputDialog:允许用户输入一个值,并返回该值
  • QMessageBox:模态对话框,用于提示信息,询问问题等
  • QProgressDialog:显示操作过程

下面以QMessageBox为例,做个简单介绍,QMessageBox用于显示信息提示,我们通常会用到以下几个静态函数:

  • void about(QWidget * parent, const QString & title, const QString & text):显示关于对话框。这是一个最简单的对话框,其标题是 title,内容是 text,父窗口是 parent。对话框只有一个 OK 按钮。
  • void aboutQt(QWidget * parent, const QString & title = QString()):显示关于 Qt 对话框。该对话框用于显示有关 Qt 的信息。
  • StandardButton critical(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton):显示严重错误对话框。这个对话框将显示一个红色的错误符号。我们可以通过 buttons 参数指明其显示的按钮。默认情况下只有一个 Ok 按钮,我们可以使用StandardButtons类型指定多种按钮。
  • StandardButton information(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)QMessageBox::information()函数与QMessageBox::critical()类似,不同之处在于这个对话框提供一个普通信息图标。
  • StandardButton question(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = StandardButtons( Yes | No ), StandardButton defaultButton = NoButton)QMessageBox::question()函数与QMessageBox::critical()类似,不同之处在于这个对话框提供一个问号图标,并且其显示的按钮是“是”和“否”两个。
  • StandardButton warning(QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton)QMessageBox::warning()函数与QMessageBox::critical()类似,不同之处在于这个对话框提供一个黄色叹号图标。

 我们通过以下示例来了解一下QMessageBox的简单使用:

if (QMessageBox::Yes == QMessageBox::question(this,"question","are you ok?",QMessageBox::Yes|QMessageBox::No,QMessageBox::Yes))    {        QMessageBox::information(this,"information","I'm glad to hear that");    }    else {        QMessageBox::information(this,"information","i'm sorry");    }

我们首先使用question来询问一个问题,然后根据用户点击的按钮不同作出相应的反应。QMessageBox类的static函数使用起来非常简单方便,如果我们需要进行定制QMessageBox,则可以通过设置其属性来实现。例如做一个询问是否需要保存的对话框:

//首先创建一个QMessagBox    QMessageBox box;    //设置对话框标题    box.setText("The document has been modified");    //设置对话框信息    box.setInformativeText("Do you want to save your changes?");    //设置详细信息,设置此属性,对话框会有一个show details的按钮,当点击该按钮时,显示详细信息    box.setDetailedText("this is detail information");    //设置对话框按钮    box.setStandardButtons(QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel);    //设置对话框默认按钮    box.setDefaultButton(QMessageBox::Save);    //显示对话框并接受返回值    int ret = box.exec();    //根据返回值不同,作出相应的操作    switch (ret) {    case QMessageBox::Save:        qDebug() << "save";        break;    case QMessageBox::Discard:        qDebug() << "discard";        break;    case QMessageBox::Cancel:        qDebug() << "cancel";        break;    default:        break;    }

运行结果如下:

我这是在Mac下,如果是在windows下,那么Qt会自动将其设置为适应windows习惯的对话框。

 

转载于:https://www.cnblogs.com/wangcb/p/6675856.html

你可能感兴趣的文章
linux配置网卡
查看>>
正则表达式语法
查看>>
013、Dockerfile构建镜像(2019-01-02 周三)
查看>>
c# mvc如何获取xml文件
查看>>
mongodb Java(八)
查看>>
JavaScript随机数
查看>>
ASP.NET验证控件——RequiredFieldValidator
查看>>
strstr
查看>>
MySQL 条件 select case 的实现(解决 零 做分母的问题 )
查看>>
openNebula rgister img instance vms error collections
查看>>
error Infos
查看>>
PL/sql配置相关
查看>>
Linux 查询服务数据
查看>>
【Luogu 2014】选课
查看>>
CSS 的介绍
查看>>
Latex自定义文档纸张大小
查看>>
2018QBXT刷题游记(23)
查看>>
函数递归
查看>>
android框架Java API接口总注释/**@hide*/和internal API
查看>>
20175318 2018-2019-2 《Java程序设计》第七周学习总结
查看>>