Qt6入门教程 9:QWidget、QMainWindow和QDialog

news2024/10/3 4:34:07

目录

一.QWidget

1.窗口和控件

2.事件

二.QMainWindow

三.QDialog

1.模态对话框

1.1模态对话框

1.2.半模态对话框

2.非模态对话框


在用Qt Creator创建Qt Widgets项目时,会默认提供三种基类以供选择,它们分别是QWidget、QMainWIndow和QDialog,其中QMainWindow和QDialog的基类都是QWidget。

一.QWidget

QWidget是所有用户界面对象的基类,它从窗口系统中接收鼠标、键盘和其他事件,并在屏幕上绘制自己。未嵌入到父窗口的小部件称为窗口,否则称之为控件。通常窗口包含边框和标题栏,当然也可用设置窗口标志(window flags)去掉窗口的边框和标题栏。在Qt中,QMainWindow和QDialog的各种子类是最常见的窗口类型。

1.窗口和控件

没有父窗口的小部件通常是独立窗口(顶层小部件),对于窗口,可以用setWindowTitle()和setWindowIcon()来设置标题栏的标题和图标。
有父窗口的小部件称为控件,它们通常内嵌到父窗口中。Qt中大多数小部件都是当控件使用的,比如,尽管标签(QLabel)可以显示为一个窗口,但一般不这么用,通常把它作为窗口的一个控件,就像前面的HelloWorld项目那样。

2.事件

小部件会响应用户操作产生的各种事件。Qt通过QEvent子类实例调用特定的事件处理函数(QEvent子类中包含每个事件的详细信息),将事件传递到小部件。
下面是与QWidget相关事件的简介。
●最常用的事件处理函数
paintEvent():小部件重绘时被调用。如果要显示自定义内容,必须实现它。使用QPainter绘制只能在paintEvent()或paintEvent()调用的函数中进行。
resizeEvent():小部件大小变化时被调用
mousePressEvent():通常在两种情况下被调用。一是鼠标指针在小部件内,并点击了鼠标按键;二是小部件通过grabMouse()函数把鼠标抢占了。按下鼠标不放和调用grabMouse()的效果是一样的。
mouseReleaseEvent():当鼠标按键释放时被调用。小部件只有在接收了相应的鼠标按下事件,才会接收鼠标释放事件,这两事件是一一对应的关系。有一个例外,如果在按住鼠标的同时弹出菜单,则此弹出菜单会立即偷走鼠标事件(进入菜单的事件循环中)。
mouseDoubleClickEvent():在小部件中双击会被调用。双击实际上是当做两次单击处理的,如果双击的时候手抖了,可能还会收到鼠标移动事件。需要注意的是,在第二次点击到达之前,是无法区分单击和双击的,所以不要试图在双击事件里处理单击逻辑。
●如果要接受键盘输入,需要多实现几个事件处理函数
keyPressEvent():当键盘按键按下是被调用。长按会重复调用。
focusInEvent():当小部件获取键盘焦点时被调用。
focusOutEvent():当小部件失去键盘焦点时被调用。
●不那么常用的事处理函数
mouseMoveEvent():当鼠标按键按下且移动鼠标时被调用。这在拖拽时非常有用。如果调用了setMouseTracking(true),不用按下鼠标也能也能触发这个事件啦。
keyReleaseEvent():在键盘按键释放时被调用。
wheelEvent():当焦点在小部件上,滚动鼠标滚轮时被调用。
enterEvent():当鼠标移动到小部件时被调用。但不包括其中的子部件,比如窗口中有个按钮,鼠标移动到按钮上并不会触发窗口的enterEvent。
leaveEvent():当鼠标移动到小部件时被调用。同理,鼠标离开了子部件,不会触发父部件的leaveEvent。
moveEvent():当小部件在父窗口中移动时被调用。
closeEvent():当小部件关闭时被调用。
有些事件并没有预置的事件处理函数,处理这些事件时,需要直接重写event()。所有的事件类型,详见:Qt Assistant—>QEvent::Type
通常情况下,如果需要嵌入到其他窗口中,则基于QWidget创建。
关于Qt的事件系统,后面会用一篇博客单独介绍。

二.QMainWindow

QMainWindow是Qt框架自带的一个预定义好的主窗口类。所谓主窗口,就是一个应用程序最顶层的窗口,比如Qt Creator就是一个主窗口。经典的主窗口通常是由一个标题栏,一个菜单栏,若干工具栏和一个任务栏组成。在这些子组件之间则是我们的工作区。事实上,QMainWindow正是这样的一种布局,如下图所示:

在QMainWindow中可以添加QMenuBar(菜单栏)、QToolBar(工具栏)、QStatusBar(状态栏)以及QDockWidget(停靠窗体)
QMainWindow中必须要有Central Widget(中心小部件),中心小部件可以是Qt自带控件,比如QTextEdit或QGraphicsView,也可以是自定义控件。可以通过setCentralWidget()函数来设置中心小部件。
当QMainWindow用于单文档(SDI)或多文档(MDI)应用程序,可以将QMdiArea设置为中心小部件。
下面是设置QTextEdit为中心小部件的代码。
●新建txt文件,将后缀改为pro,pro内容如下:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

SOURCES += \
    main.cpp

简单解释一下pro文件。首先,我们定义了QT,用于告诉编译器,需要使用哪些模块,我们通常需要添加core和gui。第二行,如果 Qt 的主版本号(QT_MAJOR_VERSION)大于4,也就是Qt5,则需要另外添加widgets(因为在Qt5中,所有组件都是在widgets 模块定义的)。SOURCES 和 HEADERS 顾名思义,就是项目所需要的源代码文件和头文件,这里不需要头文件。现在有个基本的概念即可,以后随着项目的不断增大,pro文件会越来越复杂。
●在pro同目录新建main.cpp,内容如下:

#include <QApplication>
#include <QMainWindow>
#include <QTextEdit>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;
    w.setWindowTitle("https://blog.csdn.net/caoshangpa");
    QTextEdit textEdit;
    w.setCentralWidget(&textEdit);
    w.resize(400, 300);
    w.show();
    return a.exec();
}

运行一下:


关于如何添加菜单栏、工具栏和状态栏将在下一篇中介绍。

三.QDialog

QDialog是Qt框架带来的一个预定义好的对话框类。所谓对话框,主要用于短期任务以及和用户进行简要交互,对话框也是一种顶层窗口。对话框提供返回值,可以有默认按钮。QDialog也可以有一个QSizeGrip在它的右下角,使用setSizeGripEnabled(true)设置。
还是用上面的pro,man.cpp如下:

#include <QApplication>
#include <QDialog>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QDialog w;
    w.setSizeGripEnabled(true);
    w.setWindowTitle("https://blog.csdn.net/caoshangpa");
    w.resize(400, 300);
    w.show();
    return a.exec();
}


箭头所指的就是QSizeGrip,它在无边框窗口时非常有用,可以通过拖动右下角缩放窗口。状态栏(QStatusBar)自带这个小部件,所以如果你用到了状态栏,就不需要再显式的添加QSizeGrip了。

1.模态对话框

模态对话框是阻塞同一应用程序中其它可视窗口输入的对话框。模态对话框有两种application modal(默认)和window modal
模态对话框有自己的事件循环,用户必须完成这个对话框中的交互操作,并且关闭了它之后才能访问应用程序中的其它任何窗口。显示模态对话框最常见的方法是调用其exec()函数,当用户关闭对话框,exec()将提供一个有用的返回值,此时流程控制继续从调用exec()的地方进行。
半模态对话框仅阻止访问与对话相关联的窗口,允许用户继续使用应用程序中的其他窗口。使用半模态对话框的步骤通常是调用setModal(true)或者setWindowModality(),然后show()。有别于exec(),show()立即将控制权返回给调用者。当用半模态对话框处理耗时操作时,必须周期性的调用QApplication::processEvents(),防止对话框卡死无法响应用户操作。

1.1.模态对话框

#include <QApplication>
#include <QMainWindow>
#include <QDialog>
#include <QPushButton>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;
    QDialog d(&w);
    d.setWindowTitle("CSDN");
    QPushButton pushButton;
    QObject::connect(&pushButton, &QPushButton::clicked, [&] {
        d.exec();
        qDebug() << "test";
    });
    pushButton.setText("Press Me");
    w.setCentralWidget(&pushButton);
    w.setWindowTitle("https://blog.csdn.net/caoshangpa");
    w.resize(400, 300);
    w.show();
    return a.exec();
}

运行一下:


此时,对话框关闭后才会打印“test”

1.2.半模态对话框

#include <QApplication>
#include <QMainWindow>
#include <QDialog>
#include <QPushButton>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QMainWindow w;
    QDialog d(&w);
    d.setModal(true);
    // 与上面那句效果一样.
    // d.setWindowModality(Qt::ApplicationModal);
    d.setWindowTitle("CSDN");
    QPushButton pushButton;
    QObject::connect(&pushButton, &QPushButton::clicked, [&] {
        d.show();
        qDebug() << "test";
    });
    pushButton.setText("Press Me");
    w.setCentralWidget(&pushButton);
    w.setWindowTitle("https://blog.csdn.net/caoshangpa");
    w.resize(400, 300);
    w.show();
    return a.exec();
}

或者去掉d.setModal(true);并将d.show()改为d.open(),因为d.open()与下面这两句等效:

d.setWindowModality(Qt::WindowModal);
d.show();

运行效果与模态对话框相同。不过,对话框弹出后会立即打印“test”。

2.非模态对话框

非模态对话框是和同一个程序中其它窗口操作无关的对话框。在文字处理中的查找和替换对话框通常是非模态的,允许用户同时与应用程序的主窗口和对话框进行交互。调用show()来显示非模态对话框,并立即将控制权返回给调用者。
在上面的代码中去掉d.setModal(true);就是非模态对话框了
运行一下:

对话框弹出后,继续点击按钮,可以看到,非模态对话框并不会阻塞按钮对鼠标的响应。

原文链接:Qt6入门教程 9:QWidget、QMainWindow和QDialog-CSDN博客 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1402028.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGPT五大教育潜能与四大教育风险

关于ChatGPT将对学校教育产生何种影响&#xff0c;教育界尚未达成共识。这在很大程度上反映了人们审视ChatGPT教育潜能时所采取的不同视角和立场。如果我们从前面提及的生态视角和学习者发展立场来看&#xff0c;ChatGPT可以与学习者之间建立协作、共生和进化的良性生态关系&am…

【Unity】AB包下载

【Unity】AB包下载 1.使用插件打AB包 a.AB包分类 一般地&#xff0c;将预制体作为AB包资源&#xff0c;不仅需要对预制体本身进行归类&#xff0c;还要对其涉及的动画&#xff08;AnimationClip&#xff09;、动画状态机&#xff08;AnimatorController&#xff09;、以及所…

7、机器学习中的数据泄露(Data Leakage)

找到并修复这个以微妙的方式破坏你的模型的问题。 数据泄露这个概念在kaggle算法竞赛中经常被提到,这个不同于我们通常说的生活中隐私数据暴露,而是在竞赛中经常出现某支队伍靠着对极个别feature的充分利用,立即将对手超越,成功霸占冠军位置,而且与第二名的差距远超第二名…

[足式机器人]Part2 Dr. CAN学习笔记- 最优控制Optimal Control Ch07-1最优控制问题与性能指标

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - 最优控制Optimal Control Ch07-1最优控制问题与性能指标

基于OpenSSL的SSL/TLS加密套件全解析

概述 SSL/TLS握手时&#xff0c;客户端与服务端协商加密套件是很重要的一个步骤&#xff0c;协商出加密套件后才能继续完成后续的握手和加密通信。而现在SSL/TLS协议通信的实现&#xff0c;基本都是通过OpenSSL开源库&#xff0c;本文章就主要介绍下加密套件的含义以及如何在O…

机器人制作开源方案 | 全自动导航分拣机器人

作者&#xff1a;孙国峰 董阳 张鑫源 单位&#xff1a;山东科技大学 机械电子工程学院 指导老师&#xff1a;张永超 贝广霞 1. 研究意义 1.1 研究背景 在工业生产中&#xff0c;机器人在解决企业的劳动力不足&#xff0c;提高企业劳动生产率&#xff0c;提高产品质量和降低…

【设计模式】适配器和桥接器模式有什么区别?

今天我探讨一下适配器模式和桥接模式&#xff0c;这两种模式往往容易被混淆&#xff0c;我们希望通过比较他们的区别和联系&#xff0c;能够让大家有更清晰的认识。 适配器模式&#xff1a;连接不兼容接口 当你有一个类的接口不兼容你的系统&#xff0c;而你又不希望修改这个…

【笔记】Blender4.0建模入门-3物体的基本操作

Blender入门 ——邵发 3.1 物体的移动 演示&#xff1a; 1、选中一个物体 2、选中移动工具 3、移动 - 沿坐标轴移动 - 在坐标平面内移动 - 自由移动&#xff08;不好控制&#xff09; 选中物体&#xff1a;右上的大纲窗口&#xff0c;点击物体名称&#xff0c;物体的轮…

【Python 元编程】装饰器入门指南

Python装饰器入门指南&#x1f680; 在编程世界中&#xff0c;效率和优雅的代码往往是我们所追求的目标。Python 作为一种强大且灵活的编程语言&#xff0c;提供了一个称为“装饰器”的功能&#xff0c;让我们能够以一种简洁和优雅的方式扩展和管理我们的代码。 本文旨在为初…

利用appium自动控制移动设备并提取数据

安装appium-python-client模块并启动已安装好的环境 安装appium-python-client模块 在window的虚拟环境下执行pip install appium-python-client 启动夜神模拟器&#xff0c;进入夜神模拟器所在的安装路径的bin目录下&#xff0c;进入cmd终端&#xff0c;使用adb命令建立adb…

生产环境 OpenFeign 的配置最佳实践

基础使用 OpenFeign 全方位讲解 1. 生产环境 OpenFeign 的配置事项 1.1 如何更改 OpenFeign 默认的负载均衡策略 warehouse-service: #服务提供者的微服务IDribbon:#设置对应的负载均衡类NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule1.2 开启默认的 O…

C++ //练习 2.14 下面的程序合法吗?如果合法,它将输出什么?

C Primer&#xff08;第5版&#xff09; 练习 2.14 练习 2.14 下面的程序合法吗&#xff1f;如果合法&#xff0c;它将输出什么&#xff1f; int i 100, sum 0; for(int i 0; i ! 10; i)sum i; std::cout<<i<<" "<<sum<<std::endl;环境…

scipy通过快速傅里叶变换实现滤波

文章目录 fft模块简介fft函数示例滤波 fft模块简介 scipy官网宣称&#xff0c;fftpack模块将不再更新&#xff0c;或许不久之后将被废弃&#xff0c;也就是说fft将是唯一的傅里叶变换模块。 Fourier变换极其逆变换在数学上的定义如下 F ( ω ) ∫ − ∞ ∞ f ( t ) e − i ω…

Python图像处理【19】基于霍夫变换的目标检测

基于霍夫变换的目标检测 0. 前言1. 使用圆形霍夫变换统计图像中圆形对象2. 使用渐进概率霍夫变换检测直线2.1 渐进霍夫变换原理2.2 直线检测 3. 使用广义霍夫变换检测任意形状的对象3.1 广义霍夫变换原理3.2 检测自定义形状 小结系列链接 0. 前言 霍夫变换 (Hough Transform,…

2024最新:optee系统开发精讲 - 课程介绍

&#xff08;本课程中如有涉及代码或硬件架构&#xff0c;则对应的版本号&#xff1a;TF-A 2.80&#xff0c;optee 3.20, Linux Kernel 6.3&#xff0c;armv8.79.0的aarch64&#xff09; &#xff08;注意&#xff1a; 该课程没有PPT&#xff0c;该课程是对照代码讲解的&#x…

回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于ABC-SVR人工蜂群算法优化支持向量机的数据多输入单输出回归预测预测效果基本描述程序设计参考资料 预测效果 基本描述 1.Matlab基于ABC-SVR人工蜂群算法优化支持…

矩阵重叠问题判断

创作背景 看到一道题目有感而发想写一篇题解&#xff0c;涉及的是一种逆向思维 桌面窗体重叠 - 洛谷https://www.luogu.com.cn/problem/U399827题目来源于《信息学奥赛课课通》 大致就是给一个长方形的左上顶点坐标&#xff08;x1,y1&#xff09;和右下顶点坐标&#xff08;x…

面试题:SpringBoot项目怎么设计业务操作日志功能?

文章目录 前言需求描述与分析系统日志操作日志 设计思路Spring AOPFilter和HandlerInterceptorSpringAOP、过滤器、拦截器对比 实现方案环境配置依赖配置表结构设计代码实现 测试调试方法验证结果 总结 前言 很久以前都想写这篇文章&#xff0c;一直没有空&#xff0c;但直到现…

【QT+QGIS跨平台编译】之一:【sqlite+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、sqlite3介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、sqlite3介绍 SQLite是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的&…

MSVS C# Matlab的混合编程系列2 - 构建一个复杂(含多个M文件)的动态库:

前言: 本节我们尝试将一个有很多函数和文件的Matlab算法文件集成到C#的项目里面。 本文缩语: MT = Matlab 问题提出: 1 我们有一个比较复杂的Matlab文件: 这个MATLAB的算法,写了很多的算法函数在其他的M文件里面,这样,前面博客的方法就不够用了。会报错: 解决办法如下…