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_H2、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。