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

目录

一.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.mfbz.cn/a/338959.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

<蓝桥杯软件赛>零基础备赛20周--第15周--快速幂+素数

报名明年4月蓝桥杯软件赛的同学们&#xff0c;如果你是大一零基础&#xff0c;目前懵懂中&#xff0c;不知该怎么办&#xff0c;可以看看本博客系列&#xff1a;备赛20周合集 20周的完整安排请点击&#xff1a;20周计划 每周发1个博客&#xff0c;共20周。 在QQ群上交流答疑&am…

IntelliJ IDEA 常用快捷键一览表(通用型,提高编写速度,类结构、查找和查看源码,替换与关闭,调整格式)

文章目录 IntelliJ IDEA 常用快捷键一览表1-IDEA的日常快捷键第1组&#xff1a;通用型第2组&#xff1a;提高编写速度&#xff08;上&#xff09;第3组&#xff1a;提高编写速度&#xff08;下&#xff09;第4组&#xff1a;类结构、查找和查看源码第5组&#xff1a;查找、替换…

1 - 搭建Redis数据库服务器|LNP+Redis

搭建Redis数据库服务器&#xff5c;LNPRedis 搭建Redis数据库服务器相关概念Redis介绍安装RedisRedis服务常用管理命令命令set 、 mset 、 get 、 mget命令keys 、 type 、 exists 、 del命令ttl 、 expire 、 move 、 flushdb 、flushall 、save、shutdown 配置文件解析 LNP …

《WebKit 技术内幕》之七(4): 渲染基础

4 WebKit软件渲染技术 4.1 软件渲染过程 在很多情况下&#xff0c;也就是没有那些需要硬件加速内容的时候&#xff08;包括但不限于CSS3 3D变形、CSS3 03D变换、WebGL和视频&#xff09;&#xff0c;WebKit可以使用软件渲染技术来完成页面的绘制工作&#xff08;除非读者强行…

Unity学习-逐帧图集动画制作

首先在文件部分创建一个Sprite Library Asset 然后点击创建出来的文件 点下面的加号添加对应的图 添加完成之后点一下Apply 然后新建一个物体 添加这三个组件 其中SpriteLibrary里面 把你刚刚创建的图集文件拉过来 Sprite Resolver选择对应的动作和图片 然后开始制作动画 An…

如何用“VMware安装Ubuntu”win11系统?

一、 下载Ubuntu 企业开源和 Linux |Ubuntu的 二、 安装 三、 启动虚拟机 选中Try or Install Ubuntu Server&#xff0c;按回车

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

文章目录 一、OpenSSL介绍二、OpenSSL配置三、Window环境下配置四、Linux环境下配置五、Mac环境下配置 一、OpenSSL介绍 OpenSSL是一个开放源代码的软件库包&#xff0c;应用程序可以使用这个包来进行安全通信&#xff0c;避免窃听&#xff0c;同时确认另一端连接者的身份。这…

基于 Redis 实现高性能、低延迟的延时消息的方案演进

&#x1f389;欢迎来系统设计专栏&#xff1a;基于 Redis 实现高性能、低延迟的延时消息的方案演进 &#x1f4dc;其他专栏&#xff1a;java面试 数据结构 源码解读 故障分析 &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是小徐&#x1f947;☁️博客首页&#xff1…

HCIA vlan练习

目录 实验拓扑 实验要求 实验步骤 1、交换机创建vlan 2、交换机上的各个接口划分到对应vlan中 3、trunk干道 4、路由器单臂路由 5、路由器DHCP设置 实验测试 华为交换机更换端口连接模式报错处理 实验拓扑 实验要求 根据图划分vlan&#xff0c;并通过DHCP给主机下发…

Tomcat的maxParameterCountmaxPostSize参数

Tomcat的maxParameterCount&maxPostSize参数 Tomcat的maxParameterCount&maxPostSize参数1.问题1.1问题现象1.2 参数总结1.3 问题总结 2 Tomcat官网的解释2.1 到https://tomcat.apache.org/找到文档入口2.2 找到文档的Reference2.3 查看配置文件的参数 3 文档看不明白&…

上位机图像处理和嵌入式模块部署(开篇)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 图像处理是现实生活当中很实用的一门技术。工业上一般采用的是机器视觉&#xff0c;以传统算法和光源控制为主&#xff0c;部分采用了深度学习技术…

回溯算法理论基础

回溯算法介绍 回溯算法与递归函数相辅相成&#xff0c;它是一种纯暴力搜索&#xff0c;可以使用剪枝等方式进行优化 解决问题 组合问题切割问题子集问题排列问题棋盘问题 可视化理解 可以理解为一种 n 叉树型结构&#xff0c;树的最大宽度为遍历的元素数量&#xff0c;树的…

vivado JTAG链、连接、IP关联规则

JTAG链 这列出了定义板上可用的不同JTAG链。每个链都列在下面<jtag_chain>以及链的名称&#xff0c;以及定义名称和链中组件的位置&#xff1a; <jtag_chains> <jtag_chain name"chain1"> <position name"0" component"part0…

MySQL不同插入方式性能对比实验

最近负责的项目需要数据同步入库MySQL&#xff0c;为了测速那种入库方式效率比较高&#xff0c;为此进行了以下的对比实验&#xff0c;在此记录一下 实验表单数据格式 实验代码 共三种方法对比 mutiSqlInsert: 一条一条插入&#xff0c;最后一次提交 singleSqlInsert&…

黑马苍穹外卖Day10学习

文章目录 Spring Task介绍cron表达式入门案例 订单状态定时处理需求分析代码开发功能测试 WebSocket介绍入门案例 来单提醒需求分析代码开发 客户催单需求分析代码开发 Spring Task 介绍 cron表达式 入门案例 订单状态定时处理 需求分析 代码开发 新建一个task包里面编写代码…

像 Google SRE 一样 OnCall

在 Google SRE 的著作《Google运维解密》(原作名&#xff1a;Site Reliability Engineering: How Google Runs Production Systems)中&#xff0c;Google SRE 的关键成员们几乎不惜用了三个章节的篇幅描述了在 Google 他们是如何 OnCall 的。 Google SRE 实践中&#xff0c;有…

HFSS笔记/信号完整性分析(二)——软件仿真设置大全

文章目录 1、多核运算设置1.1 如何设置1.2 如何查看自己电脑的core呢&#xff1f;1.3 查看求解的频点 2、求解模式设置Driven Terminal vs Driven modal 3、Design settings4、自适应网格划分5、更改字体设置 仅做笔记整理与分享。 1、多核运算设置 多核运算只对扫频才有效果&…

Django 图片上传与下载

写在前面 在Web开发中&#xff0c;文件上传和下载是常见的功能之一。 Django 是一位魔法师&#x1fa84;&#xff0c;为我们提供了 FileField 和 ImageField 等神奇得字段类型&#xff0c;以及相应的视图和模板标签&#xff0c;使得处理文件变得十分便捷。本文以图片上传作为…

GPT-4 的决策在股市中进行量化投资

论文题目:Can Large Language Models Beat Wall Street? Unveiling the Potential of AI in Stock Selection 论文链接:https://arxiv.org/abs/2401.03737 博客地址:https://www.marketsense-ai.com/ 从本质上来说&#xff0c;股票选择是个价格发现机制&#xff0c;在股票投…

深入解析ESP32C3(2)- 存储类型和地址空间

ESP32C3芯片的存储资源 • 384 KB 的ROM&#xff1a;用于程序启动和内核功能调用 • 400 KB 片上SRAM&#xff1a;用于数据和指令存储&#xff0c;时钟频率可配置&#xff0c;最大160 MHz。400 KB SRAM 中&#xff0c;有16 KB 配置为cache 专用 • RTC 快速存储器&#xff1a;…
最新文章