首页 > 其他分享 >Qt模态对话框与非模态对话框

Qt模态对话框与非模态对话框

时间:2024-08-31 15:21:41浏览次数:12  
标签:模态 窗口 Qt show 对话框 include

前言

在 Qt 中,模态对话框和非模态对话框是两种常见的对话框类型,它们的主要区别在于用户与应用程序的交互方式。

正文

对话框就是指QDialog嘛。

模态对话框 (Modal Dialog)

定义: 模态对话框是指在弹出对话框期间,用户无法与应用程序的其他部分进行交互。用户必须先处理完对话框中的内容,才能返回到主窗口或其他窗口进行操作。

特点:

  • 阻止用户交互: 在对话框打开时,主窗口和其他窗口都不可操作。
  • 强制用户处理: 用户必须关闭或处理完对话框中的内容才能继续使用应用程序的其他部分。
  • 常用场景: 用于需要用户立即响应的情况,如确认对话框、警告框或要求用户输入关键信息的场景。

实现一:

  • 使用 QDialogexec() 方法显示模态对话框。
  • 例如:
#include "widget.h"
#include <QApplication>
#include "mydialog.h"	//这是我自己定义的类你们不必添加
#include "qdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QDialog dlg;
    dlg.setWindowTitle("模态对话框");
    dlg.exec();
    Widget w;
    w.setWindowTitle("主窗口");
    w.show();

    return a.exec();
}

运行结果,可以看到只有对话框界面,没有主界面,主界面被堵塞了
在这里插入图片描述
当我把对话框页面叉掉时,看到主界面又显示了出来
在这里插入图片描述
在这里插入图片描述
实现二:

  • 使用 QDialogshow() 方法加setModel()显示模态对话框。
  • 例如:
#include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    //最好创建在堆上,这是不要学我new出来没有释放。
    QDialog* dlg  = new QDialog();
    dlg->setWindowTitle("模态对话框");
    dlg->setModal(true);
    dlg->show();

    w.setWindowTitle("主窗口");
    w.show();

    return a.exec();

}

可以看到这种方法主界面也生成了,因为show方法调用完会将调用权返回给调用者吗,于是能继续执行代码,这种窗口类似于半模态,因为我控制不了主界面,除非我将模态窗口关闭
在这里插入图片描述

非模态对话框 (Modeless Dialog)

定义: 非模态对话框是在弹出对话框期间,用户仍然可以与应用程序的其他部分进行交互。用户可以在处理对话框的同时,也操作主窗口或其他窗口。

特点:

  • 不阻止用户交互: 对话框弹出后,用户可以自由地切换回主窗口或其他窗口进行操作。
  • 灵活性高: 适用于需要与应用程序其他部分并行操作的场景。
  • 常用场景: 用于辅助功能、工具面板或设置对话框等场景。

实现:

  • 使用 QDialogshow() 方法显示非模态对话框。
  • 例如:
 #include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    QDialog dlg;
    dlg.setWindowTitle("非模态对话框");
    dlg.show();

    w.setWindowTitle("主窗口");
    w.show();

    return a.exec();

}

可以看到这里是能操纵主界面的
在这里插入图片描述

扩展:QWidget作为半模态窗口显示

实现:

  • 方法一:setWindowModality方法

Qt 中的 QWidget 对象自带 setWindowModality(type) 方法,用以设置窗口模态类型。参数 type 可选为一下三种:

Qt::NonModal 非模态:正常模式
Qt::WindowModal 半模态:窗口级模态对话框,阻塞父窗口、父窗口的父窗口及兄弟窗口。
Qt::ApplicationModal 模态:应用程序级模态对话框,阻塞整个应用程序的所有窗口。(实际上也只是半模态)

#include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setWindowTitle("QWidget实现半模态");
    w.setWindowModality(Qt::ApplicationModal);
    w.show();
    QDialog d;
    d.show();
   return a.exec();
}

但是运行发现并未实现模态效果,只是实现了半模态。
在这里插入图片描述

  • 方法二:setAttribute方法
#include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setWindowTitle("QWidget实现半模态");
    // true:模态, false:非模态
    w.setAttribute(Qt::WA_ShowModal,true);
    w.show();
    QDialog d;
    d.show();
   return a.exec();
}

设置部件(或窗口)属性也可以:

pWidget->setAttribute(Qt::WA_ShowModal, true); // 属性设置 true:模态 false:非模态
注意:QWidget 实际上实现不了真正的模态窗口,只能实现半模态窗口。

自定义模态对话框不模态问题

自定义QWidget对话框,如果通过函数

this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Dialog);

设置了对话框的显示设置后,会导致该对话框在模态显示的时候如果设置了父窗口指针,会导致模态的设置无效,这时需要在该函数中加一个参数Qt::Dialog就可以了。

//main.cpp
#include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"
#include "definedialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setWindowTitle("DefineDialog模态无效");
    //指定父窗口
    DefineDialog dfg(&w);
    //设置模态
    dfg.setWindowModality(Qt::ApplicationModal);
    dfg.show();
    w.show();
   return a.exec();
}




// DefineDialog.cpp
#include "definedialog.h"
#include "ui_definedialog.h"

DefineDialog::DefineDialog(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DefineDialog)
{
    ui->setupUi(this);
    // | Qt::Dialog 
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    //将上句改成this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Dialog );可使得模态生效
}

DefineDialog::~DefineDialog()
{
    delete ui;
}

在这里插入图片描述

PS:如果不传父窗口的指针,设置窗口状态时无论是否添加Qt::Dialog模态都是是有效的,只是这样在任务栏上弹出的窗口也会有一个独立的图标,并且在任务管理其中会多一个任务出现,这样感觉不是太好。设置父窗口后,任务栏和任务管理器中就都合并为一个了。


//main.cpp
#include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"
#include "definedialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.setWindowTitle("DefineDialog模态一定有效");
    DefineDialog dfg;
    //设置模态
    dfg.setWindowModality(Qt::ApplicationModal);
    dfg.show();
    w.show();
   return a.exec();
}




// DefineDialog.cpp
#include "definedialog.h"
#include "ui_definedialog.h"

DefineDialog::DefineDialog(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::DefineDialog)
{
    ui->setupUi(this);
    // 加不加| Qt::Dialog都可以
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
}

DefineDialog::~DefineDialog()
{
    delete ui;
}

下图就是不指定父窗口时会出现
在这里插入图片描述

关于Qt Creater快速入门(霍亚飞,第三版,51页多窗口切换例子的解读)

代码我就不全部粘出来了,书上都有,我只写一些我认为重要的

//main.cpp 
#include "widget.h"
#include <QApplication>
#include "mydialog.h"
#include "qdialog.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    // 创建子界面
    MyDialog dialog;
    // dialog.exec() == QDialog::Accepted 其实相当于两步
    // 第一步 int temp = dialog.exec(); 这一步等号右边会生成一个模态对话框
    // 第二步 temp == QDialog::Accepted
    if (dialog.exec() == QDialog::Accepted) {
        w.show();
        return a.exec();
    }
    else return 0;
}


//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "mydialog.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->btnBegin,&QPushButton::clicked,this,&Widget::showDialog);
}

Widget::~Widget()
{
    delete ui;
}


void Widget::on_btnDialog_clicked()
{
    //关闭主界面
    this->close();
    //创建子窗口对象
    MyDialog mdlg;
    // 这里mdlg.exec() == QDialog::Accepted 其实相当于两步
    // 第一步 int temp = mdlg.exec(); 这一步等号右边会生成一个模态对话框
    // 第二步 temp == QDialog::Accepted
    if (mdlg.exec() == QDialog::Accepted) this->show();
}

void Widget::showDialog()
{
    MyDialog* dlg = new MyDialog(this);
    dlg->show();
}


//MyDialog.cpp
#include "mydialog.h"
#include "ui_mydialog.h"

MyDialog::MyDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::MyDialog)
{
    ui->setupUi(this);
}

MyDialog::~MyDialog()
{
    delete ui;
}

void MyDialog::on_btnMain_clicked()
{
    // 本函数调用后会隐藏模态对话框,并返回QDialog::Accepted
    accept();
}


注意创建你的MyDialog设计师类时一定要继承QDialog
运行结果

<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="UIRAwETk-1725018534184" src="https://live.csdn.net/v/embed/421053"></iframe>

huoYafei_duochuangkouqiehuan

标签:模态,窗口,Qt,show,对话框,include
From: https://blog.csdn.net/m0_71489826/article/details/141643404

相关文章

  • C++创建GUI按钮\文本框(Windows)不用QT!!!
    一定要的:#include<windows.h>剩下的: 过程:LRESULTCALLBACKWndProc(HWNDhwnd,UINTMessage,WPARAMwParam,LPARAMlParam){switch(Message){ caseWM_CREATE:{ /*略*///HWND名称=CreateWindow(类型,显示的字,WS_CHILD|WS_VISIBLE,x,y,宽,......
  • 【Qt】Spacer
    Spacer在使用布局管理的时候,如果需要在控件之间添加一段空白,就可以使用QSpacerItem来表示。核心属性属性说明width宽度height⾼度hData⽔平⽅向的sizePolicyQSizePolicy::Ignored:忽略控件的尺⼨,不对布局产⽣影响。QSizePolicy::Minimum:......
  • Qt QString(十六进制形式) 转 int
    QString与QByteArray互转QStringstr("HelloWorld");QByteArraybytes=str.toUtf8();//QString转QByteArray方法1QStringstr("HelloWorld");QByteArraybytes=str.toLatin1();//QString转QByteArray方法2QByteArray转QStringQByteArraybytes(&......
  • Buildroot构建Qt根文件系统-思维导图-学习笔记-基于正点原子阿尔法开发板
    Buildroot构建Qt根文件系统获取Buildroot源码Buildroot源码下载地址,https://buildroot.org/本次下载的是长期支持版本移动至ubuntu后解压tarxfbuildroot-2022.02.3.tar.gz解压后的Buildroot源码配置Buildroot安装显示图形菜单需要的库sudoapt-getin......
  • Qt/C++地址转坐标/坐标转地址/逆地址解析/支持百度高德腾讯和天地图
    一、前言说明地址和经纬度坐标转换的功能必须在线使用,一般用在导航需求上,比如用户输入起点地址和终点地址,查询路线后,显示对应的路线,而实际上各大地图厂家默认支持的是给定经纬度坐标来查询(百度地图支持传入地址),但是你让用户输入经纬度坐标是不可能的,他肯定不可能知道怎么去拿到这......
  • 【python】PyQt5中富文本框QTextEdit的详细教程与应用实战
    ✨✨欢迎大家来到景天科技苑✨✨......
  • 【Qt】表单布局QFormLayout
     表单布局QFormLayoutQt还提供了QFormLayout,属于是QGridLayout的特殊情况,专⻔⽤于实现两列表单的布局.这种表单布局多⽤于让⽤⼾填写信息的场景.左侧列为提⽰,右侧列为输⼊框例子:使用QFormLayout创建表单(1)设置三个label、三个lineEdit(2)设置表单布局,将上述......
  • 我的第一个QT程序_创建项目_全程图解
    创建项目1.打开QT开发工具2.点【创建项目】在弹出的窗口的项目列表中选择【Application(Qt)】中间列选择第一项如上图。3.输入项目名称和项目保存的路径4.Buildsystem下拉列表中有三个选项,虽然Qt6主推CMake,所以可以默认,直接下一步5.类相关信息设置。这里也可以......
  • AI学会“视听”新语言,人大北邮上海AI Lab引领多模态理解革命 | ECCV2024亮点
    你是否想过,AI是如何“理解”我们这个多彩世界的呢?最近,一项由中国人民大学高瓴GeWu-Lab、北京邮电大学、上海AILab等机构联合研究的成果,为AI的“感官”升级提供了一种新思路。这项研究被收录于即将召开的计算机视觉顶级会议ECCV2024。AI的“视听盛宴”想象一下,你正在观......
  • 【Qt笔记】QListView控件详解
     目录引言一、QListView基本概念1.1定义与功能1.2架构原理二、QListView基本使用2.1创建QListView和Model2.2设置QListView的属性2.3处理用户交互三、QListView高级技巧3.1自定义委托3.2使用QStandardItemModel3.3实现拖放功能四、QListView......