Qt窗口類部件
一、窗口類部件
窗口就是沒有父部件的部件,所以又稱頂級部件。窗口類主要包括基本窗口類QWidget、對話框類QDialog和主窗口類QMainWindow三種。
QObject是Qt框架中的一個核心基類,它提供了對象模型和信號槽機制。而QPaintDevice及其子類則提供了繪制和顯示內容的功能。
Paint
= 繪制、涂畫
Device
= 設備、載體
1、QObject類
QObject類是所有Qt類的基類,它提供了對象模型和信號槽機制。任何對象要實現信號與槽機制,都必須使用Q_OBJECT宏。因此不管是否真正用到信號與槽機制,最好在所有QObject子類中都使用Q_OBJECT宏,避免出現不必要的錯誤。
#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窗口的代碼示例:
#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 子類的實例。這個中心窗口部件可以有自己的布局。
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+Ebar->addMenu("構建(&B)"); // 在菜單欄添加“構建”菜單,快捷鍵 Alt+Bbar->addMenu("調試(&D)"); // 在菜單欄添加“調試”菜單,快捷鍵 Alt+Dw.setMenuBar(bar); // 將菜單欄設置到主窗口(可省略,默認已有)// ====== 設置狀態欄 ======w.statusBar()->showMessage("狀態欄信息"); // 在主窗口底部的狀態欄顯示提示信息w.show(); // 顯示主窗口return a.exec(); // 啟動事件循環,等待并處理用戶操作
}
QMainWindow
自帶菜單欄、工具欄、狀態欄等,適合做應用主框架。QMenuBar
→ 菜單欄容器。QMenu
→ 菜單項(可以有子菜單和動作)。QStatusBar
→ 窗口底部的提示信息欄。Bar
→ 欄、條、橫條
四、對話框類QDialog
對話框窗口的基類,用于創建模態或非模態的對話框窗口。對話框是與用戶進行簡短交互的頂層窗口,通常用于顯示消息或執行一些臨時性的任務。
- 模態對話框:在模態對話框打開時,它會阻塞其父窗口或整個應用程序,直到用戶關閉對話框。這意味著用戶必須先處理對話框中的任務,才能繼續與應用程序的其他部分交互。
- 非模態對話框:非模態對話框則不會阻止用戶與其父窗口或其他窗口的交互,它獨立于主窗口運行,允許用戶同時操作多個窗口。
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×100d.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
。