ToolBar工具欄在所有窗體應用程式中都廣泛被使用,使用ToolBar可以很好的規範選單功能分類,使用者可根據選單欄來選擇不同的功能,Qt中預設自帶ToolBar元件,當我們以預設方式建立窗體時,ToolBar就被加入到了窗體中,一般是以QToolBar的方式存在於物件選單欄,如下所示。
QToolBar元件在開發中我遇到了以下這些功能,基本上可以應對大部分開發需求了,這裡就做一個總結。
頂部工具欄ToolBar
元件的定義有多種方式,我們可以直接通過程式碼生成,也可以使用圖形介面UI拖拽實現,但使用程式碼時間則更加靈活一些,ToolBar元件可以表現出多種形態.
首先來看一個簡單的生成案例,如下程式碼中我們通過屬性setAllowedAreas()
可以實現將ToolBar元件放置到上下左右四個不同的方位上面.
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 建立選單欄
QMenuBar *bar = menuBar();
this->setMenuBar(bar); // 將選單欄放入主視窗
QMenu * fileMenu = bar->addMenu("檔案"); // 建立父節點
// 新增子選單
QAction *newAction = fileMenu->addAction("新建檔案"); // 設定名字
//newAction->setIcon(QIcon("://image/1.ico")); // 設定可用圖示
fileMenu->addSeparator(); // 新增分割線
QAction *openAction = fileMenu->addAction("開啟檔案"); // 設定名字
//openAction->setIcon(QIcon("://image/2.ico")); // 設定可用圖示
// ----------------------------------------------------------
//建立工具欄
QToolBar *toolBar = new QToolBar(this); // 建立工具欄
addToolBar(Qt::LeftToolBarArea,toolBar); // 設定預設停靠範圍 [預設停靠左側]
toolBar->setAllowedAreas(Qt::TopToolBarArea |Qt::BottomToolBarArea); // 允許上下拖動
toolBar->setAllowedAreas(Qt::LeftToolBarArea |Qt::RightToolBarArea); // 允許左右拖動
toolBar->setFloatable(false); // 設定是否浮動
toolBar->setMovable(false); // 設定工具欄不允許移動
// 工具欄新增選單項
toolBar->addAction(newAction);
toolBar->addSeparator();
toolBar->addAction(openAction);
// By : LyShark
// https://www.cnblogs.com/lyshark
// ----------------------------------------------------------
// 繫結槽函式
connect(newAction,&QAction::triggered,this,[=](){
std::cout << "new action" << std::endl;
});
connect(openAction,&QAction::triggered,this,[=](){
std::cout << "open action" << std::endl;
});
}
MainWindow::~MainWindow()
{
delete ui;
}
接著通過程式碼的方式實現一個頂部選單欄,該選單欄中可以通過SetIcon(QIcon("://image/1.ico"));
指定圖示,也可以使用setShortcut(Qt::CTRL | Qt::Key_C);
為其指定特殊的快捷鍵。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 建立選單欄
QMenuBar *bar = menuBar();
this->setMenuBar(bar); //將選單欄放入主視窗
QMenu * fileMenu = bar->addMenu("檔案");
// By : LyShark
// https://www.cnblogs.com/lyshark
// 新增子選單
QAction *newAction = fileMenu->addAction("新建檔案"); // 新增名字
newAction->setIcon(QIcon(":/image/1.ico")); // 設定ICO圖示
newAction->setShortcut(Qt::CTRL | Qt::Key_A); // 設定快捷鍵ctrl+a
fileMenu->addSeparator(); // 新增分割線
QAction *openAction = fileMenu->addAction("開啟檔案");
openAction->setIcon(QIcon(":/image/2.ico"));
openAction->setShortcut(Qt::CTRL | Qt::Key_C); // 設定快捷鍵ctrl+c
// ----------------------------------------------------------
// 建立工具欄(可遮蔽掉,遮蔽掉後底部將失去控制元件欄位)
QToolBar *toolBar = new QToolBar(this); // 建立工具欄
addToolBar(Qt::BottomToolBarArea,toolBar); // 設定預設停靠範圍(停靠在底部)
toolBar->setFloatable(false); // 設定是否浮動為假
toolBar->setMovable(false); // 設定工具欄不允許移動
// 工具欄新增選單項
toolBar->addAction(newAction); // 工具欄新增[新建檔案]
toolBar->addSeparator(); // 新增分割線
toolBar->addAction(openAction); // 新增[開啟檔案]
// ----------------------------------------------------------
// 繫結訊號和槽
connect(newAction,&QAction::triggered,this,[=](){
std::cout << "new file slot" << std::endl;
});
connect(openAction,&QAction::triggered,this,[=](){
std::cout << "open file slot" << std::endl;
});
}
MainWindow::~MainWindow()
{
delete ui;
}
實現頂部選單欄二級選單,二級頂部選單與一級選單完全一致,只是在一級選單的基礎上進行了延申,如下程式碼則是定義了一個二級選單。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 多層選單導航欄
QMenuBar *MainMenu = new QMenuBar(this);
this->setMenuBar(MainMenu);
// 1.定義父級選單
QMenu *EditMenu = MainMenu->addMenu("編輯");
// 1.1 定義 EditMemu 下面的子選單
QAction *text = new QAction(EditMenu);
text->setText("編輯檔案"); // 設定文字內容
text->setShortcut(Qt::CTRL | Qt::Key_A); // 設定快捷鍵ctrl+a
text->setIcon(QIcon(":/image/1.ico")); // 增加圖示
EditMenu->addAction(text);
EditMenu->addSeparator(); // 在配置模式與編輯檔案之間增加虛線
QAction *option = new QAction(EditMenu);
option->setText("配置模式");
option->setIcon(QIcon(":/image/2.ico"));
EditMenu->addAction(option);
// 1.1.2 定義Option配置模式下的子選單
QMenu *childMenu = new QMenu();
QAction *set_file = new QAction(childMenu);
set_file->setText("設定檔案內容");
set_file->setIcon(QIcon(":/image/3.ico"));
childMenu->addAction(set_file);
QAction *read_file = new QAction(childMenu);
read_file->setText("讀取檔案內容");
read_file->setIcon(QIcon(":/image/2.ico"));
childMenu->addAction(read_file);
// ----------------------------------------------------------
// 註冊選單到窗體中
// By : LyShark
// https://www.cnblogs.com/lyshark
// 首先將childMenu註冊到option中
option->setMenu(childMenu);
// 然後再將childMenu加入到EditMenu中
EditMenu->addMenu(childMenu);
// ----------------------------------------------------------
// 繫結訊號和槽
connect(text,&QAction::triggered,this,[=](){
std::cout << "edit file slot" << std::endl;
});
connect(set_file,&QAction::triggered,this,[=](){
std::cout << "set file slot" << std::endl;
});
connect(read_file,&QAction::triggered,this,[=](){
std::cout << "read file slot" << std::endl;
});
}
MainWindow::~MainWindow()
{
delete ui;
}
Qt中的選單還可以實現任意位置的彈出,例如我們可以將右擊customContextMenuRequested()
事件,繫結到主視窗中,實現在窗體任意位置右擊都可以彈出選單欄,程式碼如下。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <iostream>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setContextMenuPolicy(Qt::CustomContextMenu);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 在主介面右擊->轉到customContextMenuRequested槽
// By : LyShark
// https://www.cnblogs.com/lyshark
void MainWindow::on_MainWindow_customContextMenuRequested(const QPoint &pos)
{
// 建立選單物件
QMenu *pMenu = new QMenu(this);
QAction *pNewTask = new QAction(tr("新建"), this);
QAction *pEditTask = new QAction(tr("編輯"), this);
QAction *pDeleteTask = new QAction(tr("刪除"), this);
// 設定屬性值編號: 1=>新建 2=>設定 3=>刪除
pNewTask->setData(1);
pEditTask->setData(2);
pDeleteTask ->setData(3);
// 把QAction物件新增到選單上
pMenu->addAction(pNewTask);
pMenu->addAction(pEditTask);
pMenu->addAction(pDeleteTask);
// 增加圖示
pNewTask->setIcon(QIcon(":/image/1.ico"));
pEditTask->setIcon(QIcon(":/image/2.ico"));
pDeleteTask->setIcon(QIcon(":/image/3.ico"));
// 連線滑鼠右鍵點選訊號
connect(pNewTask, SIGNAL(triggered()), this, SLOT(onTaskBoxContextMenuEvent()));
connect(pEditTask, SIGNAL(triggered()), this, SLOT(onTaskBoxContextMenuEvent()));
connect(pDeleteTask, SIGNAL(triggered()), SLOT(onTaskBoxContextMenuEvent()));
// 在滑鼠右鍵點選的地方顯示選單
pMenu->exec(QCursor::pos());
//釋放記憶體
QList<QAction*> list = pMenu->actions();
foreach (QAction* pAction, list) delete pAction;
delete pMenu;
}
// 處理髮送過來的訊號
void MainWindow::onTaskBoxContextMenuEvent()
{
// this->sender()就是訊號傳送者 QAction
QAction *pEven = qobject_cast<QAction *>(this->sender());
// 獲取編號: 1=>新建 2=>設定 3=>刪除
int iType = pEven->data().toInt();
switch (iType)
{
case 1:
std::cout << "新建任務" << std::endl;
break;
case 2:
std::cout << "設定任務" << std::endl;
break;
case 3:
std::cout << "刪除任務" << std::endl;
break;
default:
break;
}
}
還可以將頂部的選單通過bar->setVisible(false);
屬性將其隱藏起來,對外只展示出一個ToolBar控制元件欄位,ToolBar控制元件欄中只保留ICO圖示與底部文字描述,這樣能顯得更加清爽一些。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMenuBar>
#include <QToolBar>
#include <iostream>
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 隱藏選單欄上的右擊選單
this->setContextMenuPolicy(Qt::NoContextMenu);
// 建立基礎頂部選單並讓其隱藏
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("讀入檔案");
// 分別設定圖示
NewAction->setIcon(QIcon(":/image/1.ico"));
OpenAction->setIcon(QIcon(":/image/2.ico"));
ReadAction->setIcon(QIcon(":/image/3.ico"));
// 建立工具欄
QToolBar *toolBar = new QToolBar(this);
addToolBar(Qt::TopToolBarArea,toolBar);
// 將選單項依次新增到工具欄
toolBar->addAction(NewAction);
toolBar->addAction(OpenAction);
toolBar->addAction(ReadAction);
// 設定禁止移動屬性,工具欄預設貼在上方
toolBar->setFloatable(false);
toolBar->setMovable(false);
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
// ----------------------------------------------------------
// 繫結槽函式
// By : LyShark
// https://www.cnblogs.com/lyshark
connect(NewAction,&QAction::triggered,this,[=](){
std::cout << "new action" << std::endl;
});
connect(OpenAction,&QAction::triggered,this,[=](){
std::cout << "open action" << std::endl;
});
connect(ReadAction,&QAction::triggered,this,[=](){
std::cout << "read action" << std::endl;
});
}
MainWindow::~MainWindow()
{
delete ui;
}