C++ Qt开发:ToolBar与MenuBar菜单组件
Qt 是一個(gè)跨平臺C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺窗體應(yīng)用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實(shí)現(xiàn)圖形化開發(fā)極大的方便了開發(fā)效率,本章將重點(diǎn)介紹ToolBar工具欄組件以及與之類似的MenuBar菜單欄組件的常用方法及靈活運(yùn)用。
1.1 QToolBar 工具欄
QToolBar 是 Qt 中用于創(chuàng)建工具欄的組件,它為用戶提供了一個(gè)方便的方式來組織和訪問應(yīng)用程序中的各種工具和操作。工具欄通常用于快速訪問常用的功能,提高用戶體驗(yàn)。
1.1.1 主要特點(diǎn)
-
工具按鈕:
QToolBar主要由工具按鈕組成,每個(gè)工具按鈕代表一個(gè)功能或操作。工具按鈕可以包含文本、圖標(biāo),也可以與相應(yīng)的槽函數(shù)關(guān)聯(lián),實(shí)現(xiàn)用戶點(diǎn)擊按鈕時(shí)觸發(fā)相應(yīng)的操作。 - 分組和彈出菜單: 工具欄支持將工具按鈕分組,使界面更加清晰。還可以為工具按鈕添加彈出菜單,以提供額外的選項(xiàng)。
- 可調(diào)整性: 用戶可以在工具欄上*拖動工具按鈕,重新排列它們的位置。這增加了用戶定制界面的靈活性。
- 自定義小部件: 除了工具按鈕,工具欄還支持添加自定義的小部件,例如搜索框、進(jìn)度條等,以滿足特定需求。
- 樣式和布局: 可以通過設(shè)置樣式和布局來定制工具欄的外觀,包括工具按鈕的樣式、大小和排列方式。
以下是 QToolBar 類的一些常用方法的說明和概述,以表格形式列出:
| 方法 | 描述 |
|---|---|
QToolBar(QWidget *parent = nullptr) |
構(gòu)造函數(shù),創(chuàng)建一個(gè) QToolBar 對象。 |
addAction(QAction *action) |
向工具欄中添加一個(gè)動作。 |
addWidget(QWidget *widget) |
向工具欄中添加一個(gè)小部件。 |
addSeparator() |
向工具欄中添加一個(gè)分隔符。 |
clear() |
清除工具欄上的所有動作和小部件。 |
setOrientation(Qt::Orientation orientation) |
設(shè)置工具欄的方向,可以是水平 (Qt::Horizontal) 或垂直 (Qt::Vertical)。 |
setMovable(bool movable) |
設(shè)置工具欄是否可以被用戶移動。 |
setIconSize(const QSize &size) |
設(shè)置工具欄中動作的圖標(biāo)大小。 |
setToolButtonStyle(Qt::ToolButtonStyle style) |
設(shè)置工具按鈕的樣式,可以是文本和圖標(biāo)一起顯示、只顯示圖標(biāo)、只顯示文本等。 |
toggleViewAction() |
返回一個(gè)切換工具欄可見性的動作。 |
addWidget(QWidget *widget) |
在工具欄中添加一個(gè)自定義小部件。 |
clear() |
清除工具欄上的所有動作和小部件。 |
setAllowedAreas(Qt::ToolBarAreas areas) |
設(shè)置工具欄允許停靠的區(qū)域,可以是上、下、左、右、所有區(qū)域的組合。 |
setFloatable(bool floatable) |
設(shè)置工具欄是否可以浮動。 |
setWindowTitle(const QString &title) |
設(shè)置工具欄的標(biāo)題。 |
addWidget(QWidget *widget) |
在工具欄中添加一個(gè)自定義小部件。 |
widgetForAction(QAction *action) const |
返回與給定動作相關(guān)聯(lián)的小部件。 |
這些方法提供了對 QToolBar 進(jìn)行動作、小部件和外觀等方面的控制,使其適應(yīng)不同的應(yīng)用場景。你可以根據(jù)具體需求使用這些方法,定制工具欄的外觀和行為。
1.2 QMenuBar 菜單欄
QMenuBar 是 Qt 中用于創(chuàng)建菜單欄的組件,它提供了一種方便的方式來組織和管理應(yīng)用程序的菜單。菜單欄通常用于將應(yīng)用程序的功能劃分為不同的菜單,使用戶可以輕松訪問各種操作。
1.2.1 主要特點(diǎn)
-
菜單項(xiàng):
QMenuBar主要由菜單項(xiàng)組成,每個(gè)菜單項(xiàng)代表一個(gè)功能或操作。菜單項(xiàng)可以包含子菜單,形成層級關(guān)系,用于更好地組織功能。 - 快捷鍵: 每個(gè)菜單項(xiàng)可以關(guān)聯(lián)一個(gè)快捷鍵,用戶可以通過鍵盤快捷鍵來觸發(fā)相應(yīng)的操作。
- 分組和分割線: 菜單欄支持在菜單項(xiàng)之間添加分組和分割線,用于更好地區(qū)分不同的功能模塊。
-
動作關(guān)聯(lián): 菜單項(xiàng)通常與具體的動作(
QAction)關(guān)聯(lián),點(diǎn)擊菜單項(xiàng)時(shí)觸發(fā)相應(yīng)的動作。 -
上下文菜單:
QMenuBar也可以用作上下文菜單(右鍵菜單),在特定區(qū)域點(diǎn)擊右鍵時(shí)顯示相應(yīng)的菜單項(xiàng)。
以下是 QMenuBar 類的一些常用方法的說明和概述,以表格形式列出:
| 方法 | 描述 |
|---|---|
QMenuBar(QWidget *parent = nullptr) |
構(gòu)造函數(shù),創(chuàng)建一個(gè) QMenuBar 對象。 |
addMenu(const QString &title) |
添加一個(gè)具有給定標(biāo)題的菜單,并返回一個(gè)指向新菜單的指針。 |
addMenu(QMenu *menu) |
添加給定的菜單。 |
addSeparator() |
在菜單欄上添加一個(gè)分隔符。 |
addActions(QList<QAction*> actions) |
添加給定的動作列表到菜單欄。 |
clear() |
清除菜單欄上的所有菜單和分隔符。 |
setNativeMenuBar(bool nativeMenuBar) |
設(shè)置是否使用本地菜單欄,如果為 true,則菜單欄將使用本地系統(tǒng)的菜單欄實(shí)現(xiàn)。 |
setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopLeftCorner) |
在指定的角落放置一個(gè)小部件。 |
addMenu(QMenu *menu) |
添加給定的菜單。 |
setActiveAction(QAction *action) |
設(shè)置活動動作,該動作將在菜單欄上顯示為活動狀態(tài)。 |
addMenu(const QString &title) |
添加一個(gè)具有給定標(biāo)題的菜單,并返回一個(gè)指向新菜單的指針。 |
setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopLeftCorner) |
在指定的角落放置一個(gè)小部件。 |
clear() |
清除菜單欄上的所有菜單和分隔符。 |
setNativeMenuBar(bool nativeMenuBar) |
設(shè)置是否使用本地菜單欄,如果為 true,則菜單欄將使用本地系統(tǒng)的菜單欄實(shí)現(xiàn)。 |
setActiveAction(QAction *action) |
設(shè)置活動動作,該動作將在菜單欄上顯示為活動狀態(tài)。 |
setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopLeftCorner) |
在指定的角落放置一個(gè)小部件。 |
這些方法提供了對 QMenuBar 進(jìn)行菜單管理、外觀設(shè)置以及與其他小部件的交互等方面的控制。你可以根據(jù)具體需求使用這些方法,定制菜單欄的外觀和行為。
1.3 使用菜單組件
通常情況下ToolBar與MenuBar兩者會配合使用,在5.14.2版本中,窗體創(chuàng)建后會默認(rèn)包含一個(gè)MenuBar組件,對于老版本的Qt則會自帶一個(gè)ToolBar組件,ToolBar工具欄組件與MenuBar菜單欄組件,在所有窗體應(yīng)用程序中都廣泛被使用,使用這兩種組件可以很好的規(guī)范菜單功能分類,用戶可根據(jù)菜單欄來選擇不同的功能,實(shí)現(xiàn)靈活的用戶交互。
頂部工具欄ToolBar組件的定義有多種方式,我們可以直接通過代碼生成,也可以使用圖形界面UI添加,當(dāng)需要使用UI實(shí)現(xiàn)時(shí),只需要在MainWindow中選擇添加工具來新增,默認(rèn)會在窗口頂部增加,如果想要在四面增加可以使用Add Tool Bar to Other Area選項(xiàng)實(shí)現(xiàn);
1.3.1 應(yīng)用菜單組件
通常情況下我們不會使用UI的方式來使用工具欄,通過代碼將很容易的實(shí)現(xiàn)創(chuàng)建,如下代碼中我們通過屬性setAllowedAreas()可以實(shí)現(xiàn)將ToolBar組件放置到上下左右四個(gè)不同的方位上,通過代碼的方式實(shí)現(xiàn)一個(gè)頂部菜單欄,該菜單欄中可以通過SetIcon(QIcon("://image/.ico"));指定圖標(biāo),也可以使用setShortcut(Qt::CTRL | Qt::Key_C);為其指定特殊的快捷鍵。
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 創(chuàng)建菜單欄
// ----------------------------------------------------------
QMenuBar *bar = menuBar();
this->setMenuBar(bar); // 將菜單欄放入主窗口
QMenu * fileMenu = bar->addMenu("文件"); // 創(chuàng)建父節(jié)點(diǎn)
// 添加子菜單
QAction *newAction = fileMenu->addAction("新建文件"); // 設(shè)置名字
newAction->setIcon(QIcon("://image/file.ico")); // 設(shè)置可用圖標(biāo)
newAction->setShortcut(Qt::CTRL | Qt::Key_A); // 設(shè)置快捷鍵ctrl+a
fileMenu->addSeparator(); // 添加分割線
QAction *openAction = fileMenu->addAction("打開文件"); // 設(shè)置名字
openAction->setIcon(QIcon("://image/lock.ico")); // 設(shè)置可用圖標(biāo)
openAction->setShortcut(Qt::CTRL | Qt::Key_C); // 設(shè)置快捷鍵ctrl+c
// ----------------------------------------------------------
//創(chuàng)建工具欄 (可屏蔽掉 屏蔽掉后底部將失去控件欄位)
// ----------------------------------------------------------
QToolBar *toolBar = new QToolBar(this); // 創(chuàng)建工具欄
addToolBar(Qt::BottomToolBarArea,toolBar); // 設(shè)置默認(rèn)停靠范圍 [默認(rèn)停靠底部]
toolBar->setAllowedAreas(Qt::TopToolBarArea |Qt::BottomToolBarArea); // 允許上下拖動
toolBar->setAllowedAreas(Qt::LeftToolBarArea |Qt::RightToolBarArea); // 允許左右拖動
toolBar->setFloatable(false); // 設(shè)置是否浮動
toolBar->setMovable(false); // 設(shè)置工具欄不允許移動
// 工具欄添加菜單項(xiàng)
toolBar->addAction(newAction);
toolBar->addSeparator();
toolBar->addAction(openAction);
// ----------------------------------------------------------
// 綁定槽函數(shù)
// ----------------------------------------------------------
connect(newAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)新建文件",QMessageBox::Ok);
});
connect(openAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)打開文件",QMessageBox::Ok);
});
}
由于通過connect綁定到了每一個(gè)Action上,所以當(dāng)用戶點(diǎn)擊不同的菜單時(shí)將會觸發(fā)不同的匿名槽函數(shù),代碼中實(shí)現(xiàn)了彈窗提示,此處也可以替換成任意代碼,運(yùn)行效果圖如下所示;
1.3.2 二級菜單聯(lián)動
如上所示的生成案例實(shí)現(xiàn)了單一菜單的生成,其實(shí)QMenuBar組件同樣可實(shí)現(xiàn)二級菜單的聯(lián)動,二級頂部菜單與一級菜單完全一致,只是在一級菜單的基礎(chǔ)上進(jìn)行了延申,當(dāng)然只要遵循菜單的嵌套規(guī)則理論上我們可以無限延伸下去,當(dāng)然為了開發(fā)代碼邏輯清晰,筆者并不建議菜單層級超過三級。
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 多層菜單導(dǎo)航欄
// ----------------------------------------------------------
QMenuBar *MainMenu = new QMenuBar(this);
this->setMenuBar(MainMenu);
// 1.定義父級菜單
QMenu *EditMenu = MainMenu->addMenu("文件編輯");
// 1.1 定義 EditMemu 下面的子菜單
QAction *text = new QAction(EditMenu);
text->setText("編輯文件"); // 設(shè)置文本內(nèi)容
text->setShortcut(Qt::CTRL | Qt::Key_A); // 設(shè)置快捷鍵ctrl+a
text->setIcon(QIcon(":/image/about.ico")); // 增加圖標(biāo)
EditMenu->addAction(text);
// 在配置模式與編輯文件之間增加虛線
EditMenu->addSeparator();
QAction *option = new QAction(EditMenu);
option->setText("配置模式");
option->setIcon(QIcon(":/image/file.ico"));
EditMenu->addAction(option);
// 1.1.2 定義Option配置模式下的子菜單
QMenu *childMenu = new QMenu();
QAction *set_file = new QAction(childMenu);
set_file->setText("設(shè)置文件內(nèi)容");
set_file->setIcon(QIcon(":/image/lock.ico"));
set_file->setShortcut(Qt::CTRL | Qt::Key_B);
childMenu->addAction(set_file);
QAction *read_file = new QAction(childMenu);
read_file->setText("讀取文件內(nèi)容");
read_file->setIcon(QIcon(":/image/about.ico"));
childMenu->addAction(read_file);
read_file->setShortcut(Qt::CTRL | Qt::Key_C);
// ----------------------------------------------------------
// 注冊菜單到窗體中
// ----------------------------------------------------------
// 首先將childMenu注冊到option中
option->setMenu(childMenu);
// 然后再將childMenu加入到EditMenu中
EditMenu->addMenu(childMenu);
// ----------------------------------------------------------
// 綁定信號和槽
// ----------------------------------------------------------
connect(text,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)編輯文件",QMessageBox::Ok);
});
connect(set_file,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)設(shè)置文件",QMessageBox::Ok);
});
connect(read_file,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)讀取文件",QMessageBox::Ok);
});
}
代碼運(yùn)行后讀者可看到如下圖所示的效果,在配置模式中增加了兩個(gè)子菜單,每個(gè)子菜單分別綁定到了一個(gè)槽函數(shù)上,而其父菜單僅僅只是展示功能此處可以不增加任何實(shí)質(zhì)性的功能。
1.3.3 增加右鍵菜單
Qt中的菜單還可以實(shí)現(xiàn)任意位置的彈出,該功能的實(shí)現(xiàn)依賴于QMainWindow主窗體中的customContextMenuRequested()事件,該事件是Qt中的一個(gè)信號,通常與右鍵菜單(上下文菜單)相關(guān)。該信號在用戶請求上下文菜單時(shí)觸發(fā),例如通過右鍵單擊某個(gè)小部件(如窗口、按鈕、表格等)時(shí)。
我們可以將右擊customContextMenuRequested()事件綁定到主窗口中,實(shí)現(xiàn)在窗體任意位置右擊都可以彈出菜單欄,讀者可以直接在主界面中點(diǎn)擊右鍵轉(zhuǎn)到槽,如下圖;
當(dāng)讀者點(diǎn)擊主窗體中的右鍵時(shí)則會觸發(fā)on_MainWindow_customContextMenuRequested事件,該事件的內(nèi)部則實(shí)現(xiàn)了創(chuàng)建菜單的功能,并通過pMenu->exec(QCursor::pos())的方式顯示在鼠標(biāo)點(diǎn)擊位置處,其代碼如下所示;
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QCursor>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 設(shè)置小部件(QWidget)的上下文菜單策略
this->setContextMenuPolicy(Qt::CustomContextMenu);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 觸發(fā)右鍵創(chuàng)建菜單
void MainWindow::on_MainWindow_customContextMenuRequested(const QPoint &pos)
{
// 創(chuàng)建菜單對象
QMenu *pMenu = new QMenu(this);
QAction *pNewTask = new QAction(tr("新建菜單"), this);
QAction *pEditTask = new QAction(tr("編輯菜單"), this);
QAction *pDeleteTask = new QAction(tr("刪除菜單"), this);
// 設(shè)置屬性值編號: 1=>新建 2=>設(shè)置 3=>刪除
pNewTask->setData(1);
pEditTask->setData(2);
pDeleteTask ->setData(3);
// 把QAction對象添加到菜單上
pMenu->addAction(pNewTask);
pMenu->addAction(pEditTask);
pMenu->addAction(pDeleteTask);
// 增加圖標(biāo)
pNewTask->setIcon(QIcon(":/image/about.ico"));
pEditTask->setIcon(QIcon(":/image/file.ico"));
pDeleteTask->setIcon(QIcon(":/image/lock.ico"));
// 連接鼠標(biāo)右鍵點(diǎn)擊信號
connect(pNewTask, SIGNAL(triggered()), this, SLOT(onTaskBoxContextMenuEvent()));
connect(pEditTask, SIGNAL(triggered()), this, SLOT(onTaskBoxContextMenuEvent()));
connect(pDeleteTask, SIGNAL(triggered()), SLOT(onTaskBoxContextMenuEvent()));
// 在鼠標(biāo)右鍵點(diǎn)擊的地方顯示菜單
pMenu->exec(QCursor::pos());
//釋放內(nèi)存
QList<QAction*> list = pMenu->actions();
foreach (QAction* pAction, list) delete pAction;
delete pMenu;
}
接著就需要綁定到特定的槽函數(shù)上,用于接收用戶點(diǎn)擊的菜單選項(xiàng),并根據(jù)選項(xiàng)做出相應(yīng)的判斷,這里我們定義一個(gè)onTaskBoxContextMenuEvent函數(shù),并在MainWindow.h頭文件進(jìn)行聲明,其實(shí)現(xiàn)部分如下所示;
// 處理發(fā)送過來的信號
void MainWindow::onTaskBoxContextMenuEvent()
{
// this->sender()就是信號發(fā)送者 QAction
QAction *pEven = qobject_cast<QAction *>(this->sender());
// 獲取編號: 1=>新建 2=>設(shè)置 3=>刪除
int iType = pEven->data().toInt();
switch (iType)
{
case 1:
QMessageBox::information(nullptr,"提示","觸發(fā)新建任務(wù)",QMessageBox::Ok);
break;
case 2:
QMessageBox::information(nullptr,"提示","觸發(fā)設(shè)置任務(wù)",QMessageBox::Ok);
break;
case 3:
QMessageBox::information(nullptr,"提示","觸發(fā)刪除任務(wù)",QMessageBox::Ok);
break;
default:
break;
}
}
至此當(dāng)我們再次使用右鍵點(diǎn)擊主頁面時(shí),則會彈出一個(gè)個(gè)性化菜單欄,如下圖所示;
1.3.4 增加頂部通欄
通常情況下我們需要頂部按鈕的排布,這有助于增加頁面的圖形化顯示效果,為了讓頁面只保留一個(gè)ToolBar組件,通常情況下會將默認(rèn)的menuBar組件進(jìn)行隱藏,隱藏的方式是通過調(diào)用setVisible(false)來實(shí)現(xiàn),對外只展示出一個(gè)ToolBar控件欄位,而在ToolBar控件欄中只保留ICO圖標(biāo)與底部文字描述,這樣能顯得更加清爽一些。
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QCursor>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 隱藏菜單欄上的右擊菜單
this->setContextMenuPolicy(Qt::NoContextMenu);
// ----------------------------------------------------------
// 創(chuàng)建menuBar組件
// ----------------------------------------------------------
// 創(chuàng)建基礎(chǔ)頂部菜單并讓其隱藏
QMenuBar *bar = menuBar();
this->setMenuBar(bar);
QMenu * fileMenu = bar->addMenu("Ptr");
// 隱藏菜單
bar->setVisible(false);
// 添加子菜單
QAction *NewAction = fileMenu->addAction("新建文件");
QAction *OpenAction = fileMenu->addAction("打開文件");
QAction *ReadAction = fileMenu->addAction("讀入文件");
// 分別設(shè)置圖標(biāo)
NewAction->setIcon(QIcon(":/image/about.ico"));
OpenAction->setIcon(QIcon(":/image/file.ico"));
ReadAction->setIcon(QIcon(":/image/lock.ico"));
// 創(chuàng)建工具欄
QToolBar *toolBar = new QToolBar(this);
addToolBar(Qt::TopToolBarArea,toolBar);
// 將菜單項(xiàng)依次添加到工具欄
toolBar->addAction(NewAction);
toolBar->addAction(OpenAction);
toolBar->addAction(ReadAction);
// 設(shè)置禁止移動屬性,工具欄默認(rèn)貼在上方
toolBar->setFloatable(false);
toolBar->setMovable(false);
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
// ----------------------------------------------------------
// 綁定槽函數(shù)
// ----------------------------------------------------------
connect(NewAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)新建文件按鈕",QMessageBox::Ok);
});
connect(OpenAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)打開文件按鈕",QMessageBox::Ok);
});
connect(ReadAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","觸發(fā)讀取文件按鈕",QMessageBox::Ok);
});
}
運(yùn)行后讀者可看到如下圖所示的案例,我們只保留了最基本的按鈕欄,這樣看起來更加的清爽。
總結(jié)
以上是生活随笔為你收集整理的C++ Qt开发:ToolBar与MenuBar菜单组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的zsh简单设置
- 下一篇: flash怎么模拟曲柄运动的动态图