当前位置: 首页 > 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都能满足需求。

http://www.lryc.cn/news/423292.html

相关文章:

  • Spring 事务机制
  • Android 13 GMS 内置壁纸
  • 【LeetCode】234. 回文链表
  • 零基础学会机器学习,到底要多久?
  • 视频汇聚/安防监控综合平台EasyCVR接入海康私有协议EHOME显示失败是什么原因?
  • Qt解析XML
  • PwnLab: init-文件包含、shell反弹、提权--靶机渗透思路讲解
  • OpenCV—二值化Threshold()、adaptiveThreshold()
  • 第二天:java面向对象编程(OOP)
  • Selenium + Python 自动化测试07(滑块的操作方法)
  • 三防平板满足多样化定制为工业领域打造硬件解决方案
  • pytorch,用lenet5识别cifar10数据集(训练+测试+单张图片识别)
  • Word卡顿的处理方法
  • 在 Linux上常见的10大压缩格式解压命令和它们对应的压缩格式
  • 【数据结构】三、栈和队列:6.链队列、双端队列、队列的应用(树的层次遍历、广度优先BFS、先来先服务FCFS)
  • 技术速递|使用 Native Library Interop 为 .NET MAUI 创建绑定
  • Linux笔记 --- 标准IO
  • 洛谷:B3625 迷宫寻路
  • 【C#】explicit、implicit与operator
  • Vue:Vuex-Store使用指南
  • 对经典动态规划问题【爬台阶】的一些思考
  • 开发一个能打造虚拟带货直播间的工具!
  • 汽车补光照明实验太阳光模拟器光源
  • MediaPipe人体姿态、手指关键点检测
  • 树上dp之换根dp
  • 2024/8/13 英语每日一段
  • Java多线程练习(1)
  • AI高级肖像动画神器LivePortrait
  • Java反射机制深度解析与实践应用
  • Oracle递归查询层级及路径