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 guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsSOURCES += \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.hqwc.cn/news/421533.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据库复试—关系数据库标准语言SQL

数据库复试—关系数据库标准语言SQL SQL&#xff1a;结构化查询语言 以教材中的学生-课程数据库为例进行SQL基础语法的复习 数据库实验环境选择SQLServer 11 关系模式 学生表Student(Sno,Sname,Ssex,Sage,Sdept) 课程表Course(Cno,Cname,Cpno,Ccredit) 学生选课表SC&#xf…

数学建模学习笔记||层次分析法

评价类问题 解决评价类问题首先需要想到一下三个问题 我们评价的目标是什么我们为了达到这个目标有哪几种可行方案评价的准则或者说指标是什么 对于以上三个问题&#xff0c;我们可以根据题目中的背景材料&#xff0c;常识以及网上收集到的参考资料进行结合&#xff0c;从而筛…

Python语法进阶——类

Python中的数据类型都属于类。int、str、list都是Python定义好的数据类型类。 print(type(list))#<class type> print(type(list()))#<class list> 一、自定义数据类型 一、语法 class 类名():pass #类名 要求首字母大写 #()可写可省略。 #pass在这里只是用来保证…

【大模型研究】(1):从零开始部署书生·浦语2-20B大模型,使用fastchat和webui部署测试,autodl申请2张显卡,占用显存40G可以运行

1&#xff0c;演示视频 https://www.bilibili.com/video/BV1pT4y1h7Af/ 【大模型研究】&#xff08;1&#xff09;&#xff1a;从零开始部署书生浦语2-20B大模型&#xff0c;使用fastchat和webui部署测试&#xff0c;autodl申请2张显卡&#xff0c;占用显存40G可以运行 2&…

【Python学习】Python学习21- 正则表达式(1)

目录 【Python学习】Python学习21- 正则表达式&#xff08;1&#xff09; 前言re.match函数实例 re.search方法re.match与re.search的区别参考 文章所属专区 Python学习 前言 本章节主要说明Python的正则表达式。 正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的…

课题学习(十九)----Allan方差:陀螺仪噪声分析

一、介绍 Allan方差是一种分析时域数据序列的方法&#xff0c;用于测量振荡器的频率稳定性。该方法还可用于确定系统中作为平均时间函数的本征噪声。该方法易于计算和理解&#xff0c;是目前最流行的识别和量化惯性传感器数据中存在的不同噪声项的方法之一。该方法的结果与适用…

Unity 抽象工厂模式(实例详解)

文章目录 简介实例1实例2 简介 抽象工厂模式是一种创建型设计模式&#xff0c;它提供了一种方式来封装一组相关或相互依赖对象的创建过程&#xff0c;而无需指定具体类。这种模式常用于系统中有多组相关产品族&#xff0c;且客户端需要使用不同产品族中的对象时。 在Unity中&a…

Go使用记忆化搜索的套路【以20240121力扣每日一题为例】

题目 分析 这道题很明显记忆化搜索&#xff0c;用py很容易写出来 Python class Solution:def splitArray(self, nums: List[int], k: int) -> int:n len(nums)# 寻找分割子数组中和的最小的最大值s [0]for num in nums:s.append(s[-1] num)#print(s)cachedef dfs(cur,…

140:leaflet加载here地图(v2软件多种形式)

第140个 点击查看专栏目录 本示例介绍如何在vue+leaflet中添加HERE地图(v2版本的软件),并且含多种的表现形式。包括地图类型,文字标记的设置、语言的选择、PPI的设定。 v3版本和v2版本有很大的区别,关键是引用方法上,请参考文章尾部的API链接。 直接复制下面的 vue+leaf…

chisel入门初步1——基4的booth编码的单周期有符号乘法器实现

基4的booth编码乘法器原理说明 基2的booth编码 本质来说就是一个裂项重组&#xff0c;乘法器最重要的设计是改变部分积的数量&#xff0c;另外在考虑有符号数的情况下&#xff0c;最高位符号位有特别的意义。 &#xff08;注&#xff1a;部分积是指需要最后一起加和的所有部分…

[足式机器人]Part2 Dr. CAN学习笔记- 最优控制Optimal Control Ch07-3 线性二次型调节器(LQR)

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - 最优控制Optimal Control Ch07-3 线性二次型调节器&#xff08;LQR&#xff09; 1. 数学推导2. 案例反洗与代码详解 1. 数学推导 2. 案例反洗与代码详解

深度了解六西格玛培训:用MINITAB软件优化数据处理和项目管理——张驰咨询

在追求卓越的道路上&#xff0c;六西格玛培训不仅是一种管理哲学&#xff0c;更是一套科学精细的工具箱。它起源于摩托罗拉的制造车间&#xff0c;但如今它的精粹已经应用到各个行业&#xff0c;无论规模大小&#xff0c;都在追求完美的产品和服务质量。 在张驰咨询&#xff0…