当前位置: 首页 > news >正文

Qt 实战(9)窗体 | 9.2、QDialog

文章目录

  • 一、QDialog
    • 1、基本概念
    • 2、常用特性
      • 2.1、模态与非模态
      • 2.2、数据交互
    • 3、总结

前言:

Qt框架中的QDialog类是一个功能强大且灵活的对话框控件,广泛应用于各种GUI(图形用户界面)应用程序中,用于处理用户输入、消息显示、设置调整等场景。通过掌握QDialog的用法,开发者可以轻松地在Qt项目中添加和管理对话框组件,提升用户交互体验。

一、QDialog

1、基本概念

对话框:在主窗口中操作,有可能触发某一个行为动作,会弹出一个新的对话窗口,解决一个临时性的会话,在对话窗口中执行某一个功能。QDialog可以作为自定义对话框的基类,同时Qt也提供了一些标准对话框,例如:QFileDialogQColorDialog等,下面是QDialog类的继承结构,如下:

在这里插入图片描述

2、常用特性

2.1、模态与非模态

对话框常用的显示模式有两种,模态与非模态

  • 模态:不可以对其它窗口进行操作,调用exec()方法显示。在对话框关闭时,exec()方法会返回一个整数值,表示对话框的关闭方式(如接受、拒绝等)。
  • 非模态:可以对其它窗口进行操作,调用show()方法显示。通常不直接返回结果,而是需要通过其他方式(如信号和槽)来获取用户输入或对话框的状态。

模态对话框又分成程序级别(Qt::ApplicationModal)与窗口级别(Qt::WindowModal),通过QWidget::setWindowModality()方法可以设置该属性,两者的区别如下:

  • Qt::WindowModal:标志窗体的模态特性仅仅是作用于本窗体所在的继承层次上,也就是说本窗体的父窗体、上层的多个祖先窗体、本窗体的兄弟窗体及兄弟窗体的父窗体及其上层的多个祖先窗体的输入、响应都会被阻塞、挂起。
  • Qt::ApplicationModal:标志窗体的模态特性作用在整个应用程序级别。只要本窗体得不到用户响应,则该应用程序所有其它窗体,用户都无法操作,即其它窗体都不响应用户的输入操作(如:键盘、鼠标操作)。

示例一:模态对话框

在Qt中,以模态方式展示对话框非常直接,例如:

MyDialog dialog;  
if (dialog.exec() == QDialog::Accepted) {  // 用户点击了确定按钮或等效操作  // 处理用户输入或执行其他操作  
} else {  // 用户点击了取消按钮或关闭了对话框  // 执行取消操作或忽略用户输入  
}

示例二:非模态对话框

在Qt中,使用非模态的方式打开对话框意味着对话框在显示后不会阻塞用户对程序其他部分的交互。这通常是通过调用对话框的show()方法来实现的,以下是一个使用非模态方式打开对话框的简单例子:

// MainWindow.cpp 或其他源文件中  
#include "MyNonModalDialog.h"  // 假设这是MainWindow类的一个成员函数  
void MainWindow::openNonModalDialog()  
{  // 创建MyNonModalDialog的实例  MyNonModalDialog *dialog = new MyNonModalDialog(this); // 将this作为父对象,以便在MainWindow被销毁时自动销毁dialog  // 显示对话框  dialog->show();  // 注意:这里不需要等待对话框关闭,因为它是非模态的  // 用户可以继续与MainWindow或其他窗口交互  
}  

注意: 通常需要使用new操作符动态创建,并在适当的时候手动删除。然而,在某些情况下,也可以利用Qt的父子对象系统来自动管理非模态对话框的生命周期。例如:调用QWidget::setAttribute()方法,属性设置成Qt::WA_DeleteOnClose,当窗口关闭时会自动释放内存。

QDialog对象在exec()执行完毕后的状态

重要的是要理解exec()的返回值和对象的生命周期是两个不同的概念。

  • 返回值exec()方法有一个返回值,通常是QDialog::AcceptedQDialog::Rejected,这取决于用户是如何关闭对话框的(比如点击了“确定”按钮还是“取消”按钮)。这个返回值是在对话框关闭并且事件循环结束后返回的。
  • 对象生命周期QDialog对象(以及任何Qt对象)的生命周期是由其智能指针(如QSharedPointerQPointer,但更常见的是QObject的父子关系)或原始指针(QDialog*)的管理方式决定的。仅仅因为exec()方法执行完毕并返回了,并不意味着QDialog对象就被销毁了。
    • 如果QDialog对象是通过new关键字在堆上创建的,并且没有通过delete显式删除,也没有被任何智能指针管理,那么它的生命周期将一直持续到程序结束或它被显式删除。
    • 如果QDialog对象被设置为另一个QObject的子对象(通过调用setParent()),那么它的生命周期将绑定到其父对象的生命周期上。当父对象被销毁时,子对象也会被销毁(除非子对象被设置为不随父对象销毁)。

注意: 执行完exec(),当该函数返回后,如果QDialog对象的生命周期没有结束,就可以正常使用该对象。

2.2、数据交互

实际使用过程会经常涉及到与QDialog之间的数据交互,下面是常用的两种方式

  • 自定义信号
  • 结合std::bind()std::function()把类成员函数作为回调

方法一:自定义信号解决数据交互

// MyDialog.h
class MyDialog : public QDialog
{Q_OBJECT
public:explicit MyDialog(QWidget *pParent);signals:void CustomSignal(QString text);
};// MainWindow.cpp 或其他源文件中  
#include "MyDialog.h"  // 假设这是MainWindow类的一个成员函数  
void MainWindow::ShowDialog()
{// 创建MyDialog的实例  MyDialog *dialog = new MyDialog(this);connect(dialog, SIGNAL(CustomSignal(QString), this, SLOT(OnCustomSignal(QString)));dialog->exec();
}void MainWindow::OnCustomSignal(QString text)
{// 处理逻辑
}

方法二:类成员函数作为回调

// 创建 function 对象
template<typename T>
static GeneralCB CreateCB(void (T::*func)(QString), T* object)
{if (object){return std::bind(func, object, std::placeholders::_1);}return nullptr;
}class MyDialog : public QDialog
{Q_OBJECT
public:explicit MyDialog(QWidget *pParent);public:GeneralCB m_cb;
};// MainWindow.cpp 或其他源文件中  
#include "MyDialog.h"  // 假设这是MainWindow类的一个成员函数  
void MainWindow::openNonModalDialog()
{// 创建MyNonModalDialog的实例  MyDialog *dialog = new MyDialog(this);dialog->m_cb = CreateCB(MainWindow::OnCustomFunc, this);dialog->exec();
}void MainWindow::OnCustomFunc(QString text)
{// 处理逻辑
}

3、总结

QDialog是Qt中创建对话框的强大工具,通过它,可以轻松地实现各种复杂的用户交互场景。无论是简单的消息提示还是复杂的配置窗口,QDialog都能满足需求。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【秋招笔试】8.11大疆秋招(第二套)-测开岗
  • 如何使用 Jupyter Notebook
  • 1Panel配置
  • C++(27): 线程池
  • 【自动驾驶】自定义消息格式的话题通信(C++版本)
  • 【CS.DB】数据库-关系型数据库-MySQL-3.4.数据的插入_查询_更新和删除
  • 安防监控/视频汇聚平台EasyCVR如何配置,实现默认获取设备的子码流?
  • 探索NSAppleScript的魔法:Objective-C与AppleScript的无缝对接
  • centos7系统更新阿里镜像源地址
  • Java流程控制01:用户交互Scanner
  • 如何将列数据转换为行数据——SQL和EF Core(C#)两种实现方式
  • 【Linux】
  • Java开发代码规范文档
  • windows 安装TVM
  • NCL的安装和运行;气象数据可视化;散点图、直方图、等值线图、箭头图、任意折线和任意图形、非规则网格、图形叠加、组图的绘制
  • 【EOS】Cleos基础
  • 2017年终总结、随想
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • create-react-app做的留言板
  • Date型的使用
  • FastReport在线报表设计器工作原理
  • gops —— Go 程序诊断分析工具
  • iOS 系统授权开发
  • Java Agent 学习笔记
  • Mocha测试初探
  • node学习系列之简单文件上传
  • PHP 7 修改了什么呢 -- 2
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • Solarized Scheme
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • Vue 2.3、2.4 知识点小结
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 记一次删除Git记录中的大文件的过程
  • 看图轻松理解数据结构与算法系列(基于数组的栈)
  • 前端_面试
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 通过npm或yarn自动生成vue组件
  • 学习Vue.js的五个小例子
  • 一、python与pycharm的安装
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 优秀架构师必须掌握的架构思维
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ​油烟净化器电源安全,保障健康餐饮生活
  • #《AI中文版》V3 第 1 章 概述
  • #565. 查找之大编号
  • #FPGA(基础知识)
  • #微信小程序:微信小程序常见的配置传旨
  • #我与Java虚拟机的故事#连载06:收获颇多的经典之作
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (附源码)springboot青少年公共卫生教育平台 毕业设计 643214
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (一)VirtualBox安装增强功能