Qt窗口类部件
一、窗口类部件
窗口就是没有父部件的部件,所以又称顶级部件。窗口类主要包括基本窗口类QWidget、对话框类QDialog和主窗口类QMainWindow三种。

QObject是Qt框架中的一个核心基类,它提供了对象模型和信号槽机制。而QPaintDevice及其子类则提供了绘制和显示内容的功能。
Paint
= 绘制、涂画
Device
= 设备、载体
1、QObject类
QObject类是所有Qt类的基类,它提供了对象模型和信号槽机制。任何对象要实现信号与槽机制,都必须使用Q_OBJECT宏。因此不管是否真正用到信号与槽机制,最好在所有QObject子类中都使用Q_OBJECT宏,避免出现不必要的错误。
cpp
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
class MyWidget:public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = nullptr);
};
#endif // MYWIDGET_H
2、QWidget
Qt 中所有用户界面对象的基类,是最基本的可视元素。可以作为一个独立的窗口(顶级窗口部件)存在,或者作为另一个 QWidget 的子部件(嵌入式窗口部件)。
没有划分菜单、工具栏、状态栏、主窗口 等区域。

3、QMainWindow
是 QWidget的子类,包含菜单栏,工具栏,状态栏,标题栏等,中间部分则为主窗口区域。

4、QDialog
是 QWidget 的子类,用于与用户进行简短交互,如确认操作。
对话框在外观上和基本窗口相似。通常由标题栏、客户区、边框组成,标题栏上有关闭按钮。

二、基本窗口类QWidget
QWidget类是所有用户界面类的基类,也是所有可视组件(窗口部件)的基类,所有的窗口、按钮、标签、文本框等控件都是直接或间接从QWidget
派生而来。
- 既可以作为独立窗口存在,也可以作为另一个窗口部件的子部件嵌入其中。
- 通常用于创建不带特定框架结构(如菜单栏、工具栏)的窗口或自定义界面组件。
创建QWidget窗口的代码示例:
cpp
#include "widget.h" // 引入自定义的头文件(通常包含 QWidget 子类,如果没定义可以不需要)
#include <QApplication> // 引入 QApplication 类,Qt 程序的入口类
#include <QWidget> // 引入 QWidget 类,Qt 所有控件的基类
#include <QDebug> // 引入 QDebug,方便调试时打印信息
int main(int argc, char *argv[])
{
QApplication a(argc, argv); // 创建 Qt 应用程序对象,接收命令行参数,管理整个 Qt 程序的运行环境
QWidget w; // 创建一个 QWidget 窗口对象(窗口部件实例)
w.setWindowTitle("这里是标题"); // 设置窗口的标题栏文字
w.resize(300,200); // 设置窗口的大小(宽 300,高 200),只影响用户区域,不包含标题栏和边框
w.move(500,500); // 将窗口移动到屏幕上的位置(左上角坐标为 x=500, y=500)
w.setCursor(Qt::UpArrowCursor); // 设置鼠标指针的形状为"向上箭头"光标
// w.setCursor(Qt::PointingHandCursor); // (另一种光标示例:手形光标)
w.show(); // 显示窗口(默认隐藏,必须调用 show() 才能在屏幕显示)
return a.exec(); // 启动 Qt 事件循环,等待并处理用户操作(比如鼠标、键盘、窗口事件)
}
QApplication
:整个 Qt GUI 程序必须有且只有一个,用来管理事件循环。Cursor
:(光标)QWidget
:最基础的窗口类,可以单独作为窗口,也可以作为控件嵌入其他窗口。w.setXXX(...)
:调用 QWidget 提供的接口设置窗口属性。w.show()
:把窗口显示出来。a.exec()
:进入消息循环,没有它程序会一闪而过。
三、主窗口类QMainWindow
QMainWindow类的实例是一个可以设置菜单栏、工具栏、状态栏的主应用程序窗口。主要组成部分:
- 菜单栏 (Menu Bar): 位于窗口顶部,通常包含多个菜单。
- 工具栏 (Toolbars): 可以放置在窗口的顶部、底部或两侧,包含常用的按钮和控件。
- 状态栏 (Status Bar): 位于窗口底部,显示一些临时信息或状态。
- 中心窗口部件 (Central Widget): 位于主窗口的中央区域,可以放置任何 QWidget 子类的实例。这个中心窗口部件可以有自己的布局。

cpp
int main(int argc, char *argv[])
{
QApplication a(argc, argv); // 创建 Qt 应用程序对象,管理整个应用的事件循环和资源
QMainWindow w; // 创建一个 QMainWindow 对象(主窗口),适合做应用的框架界面
w.setWindowTitle("主窗口"); // 设置窗口标题为"主窗口"
QMenuBar *bar = w.menuBar(); // 获取主窗口自带的菜单栏指针(QMainWindow 已经内置了菜单栏)
// ====== 创建一个"文件"菜单(含快捷键 Alt+F)======
QMenu *fmenu = new QMenu("文件(&F)"); // 创建"文件"菜单,&F 表示按 Alt+F 激活此菜单
fmenu->addAction("新建文件"); // 在"文件"菜单里添加一个动作(菜单项)→"新建文件"
fmenu->addMenu("访问最近文件"); // 在"文件"菜单里再添加一个子菜单 →"访问最近文件"
// ====== 把"文件"菜单加入菜单栏 ======
bar->addMenu(fmenu); // 将"文件"菜单添加到菜单栏
bar->addMenu("编辑(&E)"); // 在菜单栏添加"编辑"菜单,快捷键 Alt+E
bar->addMenu("构建(&B)"); // 在菜单栏添加"构建"菜单,快捷键 Alt+B
bar->addMenu("调试(&D)"); // 在菜单栏添加"调试"菜单,快捷键 Alt+D
w.setMenuBar(bar); // 将菜单栏设置到主窗口(可省略,默认已有)
// ====== 设置状态栏 ======
w.statusBar()->showMessage("状态栏信息"); // 在主窗口底部的状态栏显示提示信息
w.show(); // 显示主窗口
return a.exec(); // 启动事件循环,等待并处理用户操作
}
QMainWindow
自带菜单栏、工具栏、状态栏等,适合做应用主框架。QMenuBar
→ 菜单栏容器。QMenu
→ 菜单项(可以有子菜单和动作)。QStatusBar
→ 窗口底部的提示信息栏。Bar
→ 栏、条、横条
四、对话框类QDialog
对话框窗口的基类,用于创建模态或非模态的对话框窗口。对话框是与用户进行简短交互的顶层窗口,通常用于显示消息或执行一些临时性的任务。
- 模态对话框:在模态对话框打开时,它会阻塞其父窗口或整个应用程序,直到用户关闭对话框。这意味着用户必须先处理对话框中的任务,才能继续与应用程序的其他部分交互。
- 非模态对话框:非模态对话框则不会阻止用户与其父窗口或其他窗口的交互,它独立于主窗口运行,允许用户同时操作多个窗口。
cpp
int main(int argc, char* argv[])
{
QApplication a(argc, argv); // 创建应用程序对象,管理整个事件循环
Widget w; // 创建一个自定义窗口部件(Widget 继承自 QWidget)
w.show(); // 显示这个主窗口
QDialog d; // 创建一个 QDialog 对话框对象
d.setWindowTitle("对话框"); // 设置对话框标题为"对话框"
d.setModal(true); // 设置为模态对话框(对话框关闭前,无法操作主窗口)
d.resize(200, 100); // 设置对话框的大小为 200×100
d.show(); // 显示对话框(非阻塞方式)
return a.exec(); // 启动事件循环,程序进入消息处理状态
}
Widget w
:主窗口(你自定义的窗口类,通常继承自 QWidget)。QDialog d
:对话框窗口,标题是"对话框"。setModal(true)
:因为是模态对话框,所以当对话框没关闭时,不能点击主窗口。show()
:显示对话框,但不会阻塞代码(对比exec()
)。
1. 补充
-
模态(Modal)
- 阻塞用户对其他窗口的操作。
- 常用于提示用户"必须先完成当前操作"。
- 例子:弹出"保存/取消"的对话框。
-
非模态(Modeless)
- 不阻塞其他窗口,可以同时操作。
- 常用于工具窗口。
-
QDialog::show() vs QDialog::exec()
show()
→ 非阻塞,只是显示窗口,程序会继续执行。exec()
→ 阻塞,对话框关闭前,程序停在这里(常用于模态对话框)。
2. setModal(true)
与 exec()
的区别
1️⃣ setModal(true)
-
作用 :设置对话框为 模态(Modal)。
-
影响:用户在对话框没关闭前,不能操作其它窗口(比如主窗口)。
-
显示方式 :它还是要配合
show()
来显示。QDialog d; d.setModal(true); d.show(); // 模态对话框(禁止操作主窗口),但程序继续往下走 qDebug() << "这行会立刻执行";
👉 模态只是限制 用户交互 ,但 不会阻塞代码执行。
2️⃣ exec()
-
作用 :显示对话框,同时进入一个 本地事件循环。
-
影响:用户必须关闭对话框,程序代码才会往下执行。
-
等价效果 :模态 + 阻塞。
QDialog d; d.exec(); // 模态 + 阻塞,必须关闭对话框,程序才会继续 qDebug() << "只有关掉对话框,这行才会执行";
3️⃣ 区别总结
setModal(true) + show()
→ 模态非阻塞- 用户不能操作主窗口,但程序代码继续运行。
exec()
→ 模态阻塞- 用户不能操作主窗口,程序代码也会停在这里,等对话框关闭才继续。
4️⃣ 小口诀
setModal(true)
控制的是:用户能不能点主窗口。exec()
控制的是:程序能不能继续往下执行。
五、总结
1. QWidget
- 定义:Qt 所有可视化界面控件的基类(Widget = 窗口部件/控件)。
- 特点 :
- 可以作为独立窗口(如果没有父对象)。
- 可以作为子控件嵌套在别的控件里(比如按钮、文本框)。
- 提供了基本的绘制、事件处理(鼠标、键盘)、布局功能。
- 中文理解:小部件 / 控件。
- 例子 :按钮 (
QPushButton
)、标签 (QLabel
)、输入框 (QLineEdit
) 都继承自QWidget
。
2. QMainWindow
- 定义 :继承自
QWidget
的一个主窗口类,是 Qt 专门为应用程序的主界面准备的。 - 特点 :
- 内置了菜单栏(Menu Bar)、工具栏(Tool Bar)、状态栏(Status Bar)、停靠窗口(Dock Widget)、中心窗口(Central Widget)等。
- 适合用来做应用程序的主框架界面。
- 中文理解:主窗口。
- 例子 :像 Qt Creator、Word 这种有菜单栏、工具栏的程序,通常用
QMainWindow
搭建。
3. QDialog
- 定义 :继承自
QWidget
的对话框类,通常用来做临时窗口。 - 特点 :
- 默认是 模态窗口(Modal):弹出后会阻塞主窗口输入,直到关闭。
- 也可以设为 非模态(Modeless):和主窗口同时交互。
- 常用于弹出提示框、登录框、设置对话框。
- 中文理解:对话框。
- 例子 :弹出的"确认/取消"窗口就是
QDialog
。
4. 三者关系
- QObject
- 提供对象模型、信号槽机制。
- QPaintDevice
- 提供绘制接口,所有可绘制的类都要继承它(QWidget、QPixmap、QImage...)。
- QWidget
- 继承自 QObject (能发信号/槽)和 QPaintDevice(能被绘制)。
- 是所有控件的基类。
- QDialog / QMainWindow
-
都是
QWidget
的子类。 -
QMainWindow适合做"程序主界面",有完整的菜单、工具栏、状态栏。
-
QDialog适合做"临时对话框",比如登录、提示、设置。
📌 类关系图(简化版):
QObject
└── QWidget (同时继承自 QPaintDevice)
├── QDialog
└── QMainWindow
✅ 总结一句:
- QPaintDevice 给
QWidget
提供了"能画"的能力; - QObject 给
QWidget
提供了"能通信"的能力; - 所以 QWidget 是 Qt 控件的核心基类 ,在它之上才有
QDialog
和QMainWindow
。