Qt學習第四篇(主視窗和ui的使用)

ivanlee717發表於2024-06-05

QMainWindow

QMainWindow是一個為使用者提供主視窗程式的類,包含一個選單欄(menu bar)、多個工具欄(tool bars)、多個停靠部件(dock widgets)、一個狀態列(status bar)及一箇中心部件(central widget),是許多應用程式的基礎,如文字編輯器,圖片編輯器等。

image-20240604111400709

選單欄

一個主視窗最多隻有一個選單欄。位於主視窗頂部、主視窗標題欄下面。

  1. 透過QMainWindow類的menubar()函式獲取主視窗選單欄指標,如果當前視窗沒有選單欄,該函式會自動建立一個。

    QMenuBar *menuBar = w.menuBar();// 獲取主視窗的選單欄指標
    
  2. 建立選單,呼叫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();
    

    image-20240604120433923滑鼠摸住子選單的時候就會彈出子選單選項

  3. 建立選單項,呼叫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);
    
    1. QAction* activeAction() const;
      • 這個函式返回當前活動的動作(Action)。
      • 活動的動作是使用者最後選擇的動作,或者在程式中透過程式設計方式設定的動作。
    2. QAction* addAction(const QString & text);
      • 這個函式用於向選單或工具欄新增一個文字動作。
      • text 引數是要顯示在動作上的文字。
      • 返回新增的動作物件的指標。
    3. QAction* addAction(const QIcon & icon, const QString & text);
      • 這個函式用於向選單或工具欄新增一個帶圖示和文字的動作。
      • icon 引數是要顯示在動作上的圖示。
      • text 引數是要顯示在動作上的文字。
      • 返回新增的動作物件的指標。
    4. QAction* addAction(const QString & text, const QObject * receiver, const char * member, const QKeySequence & shortcut = 0);
      • 這個函式用於向選單或工具欄新增一個文字動作,並與指定的物件的槽函式關聯。
      • text 引數是要顯示在動作上的文字。
      • receiver 引數是槽函式的接收者物件。
      • member 引數是槽函式的名稱。
      • shortcut 引數是可選的鍵盤快捷鍵。
      • 返回新增的動作物件的指標。
    5. 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以及列印動作的用法。

image-20240604123844138

image-20240604123855167

透過點選各種行為,然後經過[槽函式](Qt學習第三篇(訊號槽函式的連線) - ivanlee717 - 部落格園 (cnblogs.com))的連線,可以在終端看到這些行為。

image-20240604123955086

Qt 並沒有專門的選單項類,只是使用一個QAction類,抽象出公共的動作。當我們把QAction物件新增到選單,就顯示成一個選單項,新增到工具欄,就顯示成一個工具按鈕。使用者可以透過點選選單項、點選工具欄按鈕、點選快捷鍵來啟用這個動作。

工具欄

主視窗的工具欄上可以有多個工具條,通常採用一個選單對應一個工具條的的方式,也可根據需要進行工具條的劃分。

  1. 呼叫QMainWindowd物件的成員函式addToolBar(),該函式每次呼叫都會建立一個新的工具欄,並且返回該工具欄的指標。

  2. 插入屬於工具條的項,這時工具條上新增項也是用QAction。透過QToolBar類的addAction函式新增。

  3. 工具條是一個可移動的視窗,它的停靠區域由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);
    

    這裡我們允許了工具欄移動到左右和底部,初始的位置如下:image-20240604200803264

    但是我們可以根據紅箭頭指向的位置進行拖動,image-20240604200828679

    image-20240604200843447

    image-20240604200859594

    此外,我們看到工具欄裡有一個是圖形圖示,但是其他都是字元,這就用到了我們資原始檔的配置。

    Qt的資源系統(Resource System)把影像檔案的路徑新增到.qrc檔案中。.qrc檔案是Qt用來組織和管理專案中靜態資源(如影像、樣式表、翻譯檔案等)的一種方式。資原始檔允許你以一種平臺無關的方式引用專案內的檔案,並且在編譯時,這些資源會被編譯進應用程式的二進位制檔案中,便於部署和訪問。

    具體操作步驟如之前所述,簡要回顧如下:

    1. 建立或開啟 .qrc 檔案:在Qt Creator中,透過“檔案”>“新建檔案或專案”>“Qt”>“Qt資原始檔”來建立一個新的資原始檔,或者直接在專案目錄中手動建立一個.qrc檔案。

    2. .qrc 檔案中新增影像:使用Qt Creator的資源編輯器,右鍵點選資原始檔樹,選擇“新增”>“檔案”,然後瀏覽並選擇你的影像檔案(如1.png),將其新增到資源集合中。你可以為資源指定一個邏輯路徑,例如/images/1.png,其中/images是一個自定義的字首,用於組織資源。

    3. 在程式碼中引用資源:一旦影像被新增到資原始檔,你就可以透過資源的URL(如":/images/1.png")在程式碼中引用它了。如果沒有找到具體路徑,則只顯示後續的字串

      具體的如下圖所示:

image-20240604195924055

image-20240604195946269

使用setFloatable(trueOrFalse)函式來設定工具欄可否浮動image-20240604201503363這樣就代表可以把工具欄單獨拉出整個視窗位置,false反之。

使用setMoveable(trueOrFalse)函式設定工具欄的可移動性:image-20240604201558061我們設定為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);

image-20240604224907983

停靠部件(也稱為鉚接部件、浮動視窗)

停靠部件 QDockWidget,也稱浮動視窗,可以有多個。

image-20240604225826218

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);

image-20240604230225527

image-20240604230239701

ui

image-20240605094955926

image-20240605095205160在這些地方可以進行新增和刪除部件。

使用UI檔案建立介面很輕鬆很便捷,他的原理就是每次我們儲存UI檔案的時候,QtCreator就自動幫我們將UI檔案翻譯成C++的圖形介面建立程式碼。可以透過以下步驟檢視程式碼

到工程編譯目錄,一般就是工程同級目錄下會生成另一個編譯目錄,會找到一個帶ui_字首跟ui檔案同名的.h檔案,這就是程式碼

image-20240605110313495

image-20240605110521461

程式碼內容為:image-20240605110623344

在專案MainWindow的建構函式中會呼叫這個函式來初始化視窗,其實這裡邊就是初始化我們的各個控制元件。image-20240605110741974

ui使用訊號槽

在UI編輯介面中使用訊號和槽很方便,比如,拖出一個Button到視窗上,右鍵這個button,選擇轉到槽:image-20240605111130565

此時會出現這個控制元件(QPushButton)可以連線的各個訊號,我們可以根據具體需求選中訊號來建立一個連線這個訊號的槽函式:image-20240605111210170

以click(bool)訊號為例,建立了一個槽函式。這個槽函式是QtCreator自動幫我們建立的,而且也使用生成C++程式碼的方式幫我們做好了連線,我們可以直接在這個函式體內實現功能就行。很方便,比使用Lambda表示式還方便。image-20240605111331495

可以使用動作編輯器旁邊的訊號槽編輯器,裡邊也可以新增訊號和槽的連線,比如新增PushButton的clicked訊號和radioButton槽的連線:image-20240605111750193

按住F4鍵就可以看到相互的關係

image-20240605111837764

相關文章