【Qt】对话框QDialog

文章目录

对话框QDialog

基本概念

对话框是 GUI 程序中不可或缺的组成部分。很多不能或者不适合放入主窗口的功能组件都必须放在对话框中设置。对话框通常会是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互


Qt 中使用QDialog类实现对话框,像主窗口一样,我们通常会设计一个类继承QDialog:

QDialog(及其子类,以及所有Qt::Dialog类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。

  • 顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置

对话框分类

对话框分为模态对话框和非模态对话框

  • 模态对话框:会阻塞同一应用程序中其它窗口的输入。比如:"打开文件"功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的
  • 非模态对话框:创建对话框后可以对其他窗口进行操作。例如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑

标准对话框

标准对话框,是 Qt 内置的一系列对话框,比如有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等

Qt 的内置对话框大致分为以下几类:

  • Q C o l o r D i a l o g QColorDialog QColorDialog: 选择颜色
  • Q F i l e D i a l o g QFileDialog QFileDialog: 选择文件或者目录
  • Q F o n t D i a l o g QFontDialog QFontDialog: 选择字体
  • Q I n p u t D i a l o g QInputDialog QInputDialog: 允许用户输入一个值,并将其值返回
  • Q M e s s a g e B o x QMessageBox QMessageBox: 模态对话框,用于显示信息、询问问题等
  • Q P a g e S e t u p D i a l o g QPageSetupDialog QPageSetupDialog: 为打印机提供纸张相关的选项
  • Q P r i n t D i a l o g QPrintDialog QPrintDialog: 打印机配置
  • Q P r i n t P r e v i e w D i a l o g QPrintPreviewDialog QPrintPreviewDialog:打印预览
  • Q P r o g r e s s D i a l o g QProgressDialog QProgressDialog: 显示操作过程

自定义消息框

Qt 支持模态对话框和非模态对话框:

  • 使用 Q D i a l o g : : e x e c ( ) QDialog::exec() QDialog::exec()实现应用程序级别的模态对话框
  • 使用 Q D i a l o g : : o p e n ( ) QDialog::open() QDialog::open()实现窗口级别的模态对话框
  • 使用 Q D i a l o g : : s h o w ( ) QDialog::show() QDialog::show()实现非模态对话框

模态对话框

应用程序级别的模态 => 默认的方式

当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口

窗口级别的模态

该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。窗口级别的模态尤其适用于多窗口模式


例子:

cpp 复制代码
QDialog dialog;
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();

调用了exec()将对话框显示出来,当对话框出现时,我们不能与主窗口进行任何交互,直到我们关闭了该对话框,这是一个模态对话框


非模态对话框

cpp 复制代码
QDialog dialog(this);
dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.show();//将exec()修改为show()

现象:对话框竟然一闪而过,因为show()函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行

注意:此时dialog 是建立在栈上的,dialog 超出作用域被析构,因此对话框消失了,将 dialog 改成堆上建立,当然就没有这个问题了

cpp 复制代码
QDialog *dialog = new QDialog(this);
dialog->setWindowTitle(tr("Hello, dialog!"));
dialog->show();

此时仍有一个问题:此时是将对话框设置到对象树上,但是如果对内存占用有严格限制的话,当我们将主窗口作为 parent 时,主窗口不关闭,对话框就不会被销毁,所以会一直占用内存

解决办法:setAttribute()函数设置对话框关闭时,自动销毁对话框。

cpp 复制代码
dialog->setAttribute(Qt::WA_DeleteOnClose);

案例:点击新建按钮弹出对话框

ui界面如下

cpp 复制代码
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //案例:点击新建按钮=>弹出对话框
    connect(ui->actionNew,&QAction::triggered,[=](){
        //case1:创建模态对话框
        /*
            QDialog dlg(this);
            dlg.resize(200,100);//调整对话框大小
            dlg.exec();//阻塞 此时不可以对其它窗口进行操作
            qDebug() <<"模态对话框弹出";//关闭了对话框才会输出这句话
        */

        //case2:创建非模态对话框
        QDialog* dlg = new QDialog(this);
        dlg->resize(100,200);
        dlg->show();
        dlg->setAttribute(Qt::WA_DeleteOnClose);
        qDebug() <<"非模态对话框弹出";
    });
}

注意:为什么窗口模态对话框的时候,QDialog对象在栈上创建,而创建非模态对话框的时候在堆上创建?

  • 因为模态对话框会阻塞当前其它窗口操作,只有当前对话框关闭了才能操作其它窗口,所以该局部变量在对话框关闭前始终有效
  • 而非模态对话框不会阻塞当前其它窗口操作,如果dialog对象是建立在栈上的,dialog 超出作用域被析构,因此对话框消失了,所以要将 dialog 改成堆上建立

创建非模态对话框细节处:因为当前这个对象是new出来的,交给对象树,该对象在窗口关闭的时候才会释放,如果有人不断的点击新建按钮,然后又关闭,每次都会创建一个新对象,可能导致内存泄漏,所以需要设置55号属性 Q t : : W A D e l e t e O n C l o s e Qt::WA_DeleteOnClose Qt::WADeleteOnClose =>在关闭对话框的时候就把对象释放掉


消息对话框

使用上述点击新建按钮,触发不同的反应:

错误对话框 =>本质是 模态对话框

cpp 复制代码
QMessageBox::critical(this,"critical","错误");

消息对话框

复制代码
 QMessageBox::information(this,"info","信息");

提问对话框

cpp 复制代码
//参数1:父亲指针  参数2:对话框的标题  参数3:提示内容  参数4:关联的按键类型=>使用|运算指定对话框应该出现的按钮
//参数5:指定默认选择的按钮
if (QMessageBox::Save  ==  QMessageBox::question(this,"ques","提问",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
{
    //该函数的返回值就是按键类型
    qDebug() << "选择的是保存";

}
else
{
    qDebug() << "选择的是取消";
}

警告对话框

cpp 复制代码
QMessageBox::warning(this,"warning","警告");

其它标准对话框

颜色对话框

cpp 复制代码
QColor color =  QColorDialog::getColor(QColor(255,0,0));
qDebug() << "r = " << color.red() << " g = " << color.green() << " b  = " << color.blue() ;//输出选择颜色的RGB

文件对话框

cpp 复制代码
//文件对话框  参数 1:父亲指针  参数2:标题   参数3:默认打开路径  参数4:需要过滤文件格式,只要该格式的文件 =>该参数可以省略
//返回值是 选取的文件的路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","Z:","(*.txt)");
qDebug() << str;

字体对话框

cpp 复制代码
bool flag;
QFont font = QFontDialog::getFont(&flag,QFont("华文彩云",36)); //默认设置字体为华文彩云 36号字体
//QString转为char*的方法:  toUtf8().data()
qDebug() << "字体:" << font.family().toUtf8().data() << " 字号 "<< font.pointSize() << " 是否加粗"<< font.bold() << " 是否倾斜"<<font.italic();

相关推荐
C++ 老炮儿的技术栈8 分钟前
自定义CString类与MFC CString类接口对比
c语言·c++·windows·qt·mfc
·云扬·1 小时前
【PmHub后端篇】PmHub 中缓存与数据库一致性的实现方案及分析
数据库·缓存
kaixiang3001 小时前
sqli-labs靶场23-28a关(过滤)
数据库·sql
不剪发的Tony老师1 小时前
数据库行业竞争加剧,MySQL 9.3.0 企业版开始支持个人下载
数据库·mysql
淡定是个好东西2 小时前
springboot连接高斯数据库(GaussDB)踩坑指南
数据库·gaussdb
追风赶月、2 小时前
【Redis】哨兵(Sentinel)机制
数据库·redis·sentinel
20242817李臻2 小时前
20242817-李臻-课下作业:Qt和Sqlite
jvm·qt·sqlite
悟能不能悟2 小时前
mysql的not exists走索引吗
数据库·mysql
明月与玄武2 小时前
Jmeter -- JDBC驱动连接数据库超详细指南
数据库·jmeter·配置jdbc连接
专注VB编程开发20年2 小时前
VB.NET关于接口实现与简化设计的分析,封装其他类
java·前端·数据库