QMainWindow
QMainWindow是一個為使用者提供主視窗程式的類,包含一個選單欄(menu bar)、多個工具欄(tool bars)、多個停靠部件(dock widgets)、一個狀態列(status bar)及一箇中心部件(central widget),是許多應用程式的基礎,如文字編輯器,圖片編輯器等。
選單欄
一個主視窗最多隻有一個選單欄。位於主視窗頂部、主視窗標題欄下面。
-
透過QMainWindow類的menubar()函式獲取主視窗選單欄指標,如果當前視窗沒有選單欄,該函式會自動建立一個。
QMenuBar *menuBar = w.menuBar();// 獲取主視窗的選單欄指標
-
建立選單,呼叫
QMenu
的成員函式addMenu
來新增選單QAction* addMenu(QMenu * menu); QMenu* addMenu(const QString & title); QMenu* addMenu(const QIcon & icon, const QString & title);
MainWindow w; QMenuBar *menubar = w.menuBar();// 獲取主視窗的選單欄指標 QMenu *menu = menubar->addMenu("menu");// 新增主選單 QMenu *submenu = new QMenu("submenu");// 新增子選單 menu->addMenu(submenu); QAction *newAction = submenu->addAction("new action"); // 新增子選單項 w.show();
滑鼠摸住子選單的時候就會彈出子選單選項
-
建立選單項,呼叫QMenu的成員函式addAction來新增選單項
QAction* activeAction() const; QAction* addAction(const QString & text); QAction* addAction(const QIcon & icon, const QString & text); QAction* addAction(const QString & text, const QObject * receiver, const char * member, const QKeySequence & shortcut = 0); QAction* addAction(const QIcon & icon, const QString & text, const QObject * receiver, const char * member, const QKeySequence & shortcut = 0);
QAction* activeAction() const;
:- 這個函式返回當前活動的動作(Action)。
- 活動的動作是使用者最後選擇的動作,或者在程式中透過程式設計方式設定的動作。
QAction* addAction(const QString & text);
:- 這個函式用於向選單或工具欄新增一個文字動作。
text
引數是要顯示在動作上的文字。- 返回新增的動作物件的指標。
QAction* addAction(const QIcon & icon, const QString & text);
:- 這個函式用於向選單或工具欄新增一個帶圖示和文字的動作。
icon
引數是要顯示在動作上的圖示。text
引數是要顯示在動作上的文字。- 返回新增的動作物件的指標。
QAction* addAction(const QString & text, const QObject * receiver, const char * member, const QKeySequence & shortcut = 0);
:- 這個函式用於向選單或工具欄新增一個文字動作,並與指定的物件的槽函式關聯。
text
引數是要顯示在動作上的文字。receiver
引數是槽函式的接收者物件。member
引數是槽函式的名稱。shortcut
引數是可選的鍵盤快捷鍵。- 返回新增的動作物件的指標。
QAction* addAction(const QIcon & icon, const QString & text, const QObject * receiver, const char * member, const QKeySequence & shortcut = 0);
:- 這個函式用於向選單或工具欄新增一個帶圖示和文字的動作,並與指定的物件的槽函式關聯。
icon
引數是要顯示在動作上的圖示。text
引數是要顯示在動作上的文字。receiver
引數是槽函式的接收者物件。member
引數是槽函式的名稱。shortcut
引數是可選的鍵盤快捷鍵。- 返回新增的動作物件的指標。
#include "mainwindow.h"
#include <QApplication>
#include <QMainWindow>
#include <QMenu>
#include <QMenuBar>
#include <QAction>
#include <QDebug>
#include <QToolBar>
#include <QObject>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
QMenuBar *menubar = w.menuBar();// 獲取主視窗的選單欄指標
QMenu *menu = menubar->addMenu("menu");// 新增主選單
QMenu *submenu = new QMenu("submenu");// 新增子選單
menu->addMenu(submenu);
QAction *Action1 = submenu->addAction("action:kiss");
QAction *Action2 = submenu->addAction("action:hug");
qDebug() << "Active action:" << submenu->activeAction(); // 列印活動的動作
// 新增動作到工具欄
QToolBar* toolBar = w.addToolBar("Toolbar");
QAction* Action3 = toolBar->addAction("action:sleep");
QAction* Action4 = toolBar->addAction("action:play");
QObject::connect(Action1,&QAction::triggered,[&](){
qDebug() << "kiss triggered";
});
QObject::connect(Action2,&QAction::triggered,[&](){
qDebug() << "hug triggered";
});
QObject::connect(Action3,&QAction::triggered,[&](){
qDebug() << "sleep triggered";
});
QObject::connect(Action4,&QAction::triggered,[&](){
qDebug() << "play triggered";
});
w.show();
return a.exec();
}
這段程式碼裡我們使用了子選單欄和工具欄兩種方式解釋我們的action以及列印動作的用法。
透過點選各種行為,然後經過[槽函式](Qt學習第三篇(訊號槽函式的連線) - ivanlee717 - 部落格園 (cnblogs.com))的連線,可以在終端看到這些行為。
Qt 並沒有專門的選單項類,只是使用一個QAction類,抽象出公共的動作。當我們把QAction物件新增到選單,就顯示成一個選單項,新增到工具欄,就顯示成一個工具按鈕。使用者可以透過點選選單項、點選工具欄按鈕、點選快捷鍵來啟用這個動作。
工具欄
主視窗的工具欄上可以有多個工具條,通常採用一個選單對應一個工具條的的方式,也可根據需要進行工具條的劃分。
-
呼叫
QMainWindowd
物件的成員函式addToolBar()
,該函式每次呼叫都會建立一個新的工具欄,並且返回該工具欄的指標。 -
插入屬於工具條的項,這時工具條上新增項也是用QAction。透過QToolBar類的addAction函式新增。
-
工具條是一個可移動的視窗,它的停靠區域由QToolBar的allowAreas決定,包括(以下值可以透過查幫助文件allowAreas來索引到):
Qt::LeftToolBarArea
停靠在左側Qt::RightToolBarArea
停靠在右側Qt::TopToolBarArea
停靠在頂部Qt::BottomToolBarArea
停靠在底部Qt::AllToolBarAreas
以上四個位置都可停靠toolBar->addAction(new QAction(QIcon(":/images/newfile.png"), "New", &w)); toolBar->addAction(new QAction(QIcon(":/images/open.png"), "Open", &w)); toolBar->addAction(new QAction(QIcon(":/images/1.png"), "Save", &w)); // 設定工具欄可以停靠的所有區域 toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea|Qt::BottomToolBarArea);
這裡我們允許了工具欄移動到左右和底部,初始的位置如下:
但是我們可以根據紅箭頭指向的位置進行拖動,
此外,我們看到工具欄裡有一個是圖形圖示,但是其他都是字元,這就用到了我們資原始檔的配置。
Qt的資源系統(Resource System)把影像檔案的路徑新增到
.qrc
檔案中。.qrc
檔案是Qt用來組織和管理專案中靜態資源(如影像、樣式表、翻譯檔案等)的一種方式。資原始檔允許你以一種平臺無關的方式引用專案內的檔案,並且在編譯時,這些資源會被編譯進應用程式的二進位制檔案中,便於部署和訪問。具體操作步驟如之前所述,簡要回顧如下:
-
建立或開啟
.qrc
檔案:在Qt Creator中,透過“檔案”>“新建檔案或專案”>“Qt”>“Qt資原始檔”來建立一個新的資原始檔,或者直接在專案目錄中手動建立一個.qrc
檔案。 -
在
.qrc
檔案中新增影像:使用Qt Creator的資源編輯器,右鍵點選資原始檔樹,選擇“新增”>“檔案”,然後瀏覽並選擇你的影像檔案(如1.png
),將其新增到資源集合中。你可以為資源指定一個邏輯路徑,例如/images/1.png
,其中/images
是一個自定義的字首,用於組織資源。 -
在程式碼中引用資源:一旦影像被新增到資原始檔,你就可以透過資源的URL(如
":/images/1.png"
)在程式碼中引用它了。如果沒有找到具體路徑,則只顯示後續的字串具體的如下圖所示:
-
使用setFloatable(trueOrFalse)函式來設定工具欄可否浮動這樣就代表可以把工具欄單獨拉出整個視窗位置,false反之。
使用setMoveable(trueOrFalse)函式設定工具欄的可移動性:我們設定為false之後發現原來左側的一排可移動的點消失了,setMoveable(false)//工具條不可移動, 只能停靠在初始化的位置上。
狀態列
一個QMainWindow的程式最多隻有一個狀態列。QMainWindow中可以有多個的部件都使用add…名字的函式,而只有一個的部件,就直接使用獲取部件的函式,如menuBar。同理狀態列也提供了一個獲取狀態列的函式statusBar(),沒有就自動建立一個並返回狀態列的指標。
w.statusBar()->showMessage("regina");
w.statusBar()->showMessage("ivanlee",3000);//3秒消失
// 新增一個永久顯示的元件
QLabel *permenentLabel = new QLabel("permenent status");
w.statusBar()->addPermanentWidget(permenentLabel);
QProgressBar *progressBar = new QProgressBar;
w.statusBar()->addWidget(progressBar);
停靠部件(也稱為鉚接部件、浮動視窗)
停靠部件 QDockWidget,也稱浮動視窗,可以有多個。
QDockWidget
提供了dock Widget的概念,也稱為工具選項板或實用程式視窗。停靠視窗是放置在QMainWindow中心小部件周圍的停靠小部件區域中的輔助視窗。停靠視窗可以在其當前區域內移動,移動到新區域,並由終端使用者浮動(例如,取消停靠)。QDockWidget API允許程式設計師限制dock小部件移動、浮動和關閉的能力,以及它們可以放置的區域。
// 建立停靠部件1,包含一個按鈕
QDockWidget *dock1 = new QDockWidget("停靠部件1", &w);
QWidget *widgetContent1 = new QWidget(dock1);
QPushButton *button1 = new QPushButton("按鈕1", widgetContent1);
QVBoxLayout *layout1 = new QVBoxLayout(widgetContent1);
layout1->addWidget(button1);
dock1->setWidget(widgetContent1);
// 建立停靠部件2,也包含一個按鈕
QDockWidget *dock2 = new QDockWidget("停靠部件2", &w);
QWidget *widgetContent2 = new QWidget(dock2);
QPushButton *button2 = new QPushButton("按鈕2", widgetContent2);
QVBoxLayout *layout2 = new QVBoxLayout(widgetContent2);
layout2->addWidget(button2);
dock2->setWidget(widgetContent2);
// 新增停靠部件到主視窗,並設定預設停靠位置
w.addDockWidget(Qt::LeftDockWidgetArea, dock1);
w.addDockWidget(Qt::RightDockWidgetArea, dock2);
// 設定停靠部件允許停靠的範圍
dock1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::TopDockWidgetArea);
dock2->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea | Qt::BottomDockWidgetArea);
ui
在這些地方可以進行新增和刪除部件。
使用UI檔案建立介面很輕鬆很便捷,他的原理就是每次我們儲存UI檔案的時候,QtCreator就自動幫我們將UI檔案翻譯成C++的圖形介面建立程式碼。可以透過以下步驟檢視程式碼
到工程編譯目錄,一般就是工程同級目錄下會生成另一個編譯目錄,會找到一個帶ui_字首跟ui檔案同名的.h檔案,這就是程式碼
程式碼內容為:
在專案MainWindow的建構函式中會呼叫這個函式來初始化視窗,其實這裡邊就是初始化我們的各個控制元件。
ui使用訊號槽
在UI編輯介面中使用訊號和槽很方便,比如,拖出一個Button到視窗上,右鍵這個button,選擇轉到槽:
此時會出現這個控制元件(QPushButton)可以連線的各個訊號,我們可以根據具體需求選中訊號來建立一個連線這個訊號的槽函式:
以click(bool)訊號為例,建立了一個槽函式。這個槽函式是QtCreator自動幫我們建立的,而且也使用生成C++程式碼的方式幫我們做好了連線,我們可以直接在這個函式體內實現功能就行。很方便,比使用Lambda表示式還方便。
可以使用動作編輯器旁邊的訊號槽編輯器,裡邊也可以新增訊號和槽的連線,比如新增PushButton
的clicked訊號和radioButton槽的連線:
按住F4鍵就可以看到相互的關係