闽公网安备 35020302035485号
Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍ToolBar工具栏组件以及与之类似的MenuBar菜单栏组件的常用方法及灵活运用。
| 方法 | 描述 |
|---|---|
| QToolBar(QWidget *parent = nullptr) | 构造函数,创建一个 QToolBar 对象。 |
| addAction(QAction *action) | 向工具栏中添加一个动作。 |
| addWidget(QWidget *widget) | 向工具栏中添加一个小部件。 |
| addSeparator() | 向工具栏中添加一个分隔符。 |
| clear() | 清除工具栏上的所有动作和小部件。 |
| setOrientation(Qt::Orientation orientation) | 设置工具栏的方向,可以是水平 (Qt::Horizontal) 或垂直 (Qt::Vertical)。 |
| setMovable(bool movable) | 设置工具栏是否可以被用户移动。 |
| setIconSize(const QSize &size) | 设置工具栏中动作的图标大小。 |
| setToolButtonStyle(Qt::ToolButtonStyle style) | 设置工具按钮的样式,可以是文本和图标一起显示、只显示图标、只显示文本等。 |
| toggleViewAction() | 返回一个切换工具栏可见性的动作。 |
| addWidget(QWidget *widget) | 在工具栏中添加一个自定义小部件。 |
| clear() | 清除工具栏上的所有动作和小部件。 |
| setAllowedAreas(Qt::ToolBarAreas areas) | 设置工具栏允许停靠的区域,可以是上、下、左、右、所有区域的组合。 |
| setFloatable(bool floatable) | 设置工具栏是否可以浮动。 |
| setWindowTitle(const QString &title) | 设置工具栏的标题。 |
| addWidget(QWidget *widget) | 在工具栏中添加一个自定义小部件。 |
| widgetForAction(QAction *action) const | 返回与给定动作相关联的小部件。 |
这些方法提供了对 QToolBar 进行动作、小部件和外观等方面的控制,使其适应不同的应用场景。你可以根据具体需求使用这些方法,定制工具栏的外观和行为。
| 方法 | 描述 |
|---|---|
| QMenuBar(QWidget *parent = nullptr) | 构造函数,创建一个 QMenuBar 对象。 |
| addMenu(const QString &title) | 添加一个具有给定标题的菜单,并返回一个指向新菜单的指针。 |
| addMenu(QMenu *menu) | 添加给定的菜单。 |
| addSeparator() | 在菜单栏上添加一个分隔符。 |
| addActions(QList<QAction*> actions) | 添加给定的动作列表到菜单栏。 |
| clear() | 清除菜单栏上的所有菜单和分隔符。 |
| setNativeMenuBar(bool nativeMenuBar) | 设置是否使用本地菜单栏,如果为 true,则菜单栏将使用本地系统的菜单栏实现。 |
| setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopLeftCorner) | 在指定的角落放置一个小部件。 |
| addMenu(QMenu *menu) | 添加给定的菜单。 |
| setActiveAction(QAction *action) | 设置活动动作,该动作将在菜单栏上显示为活动状态。 |
| addMenu(const QString &title) | 添加一个具有给定标题的菜单,并返回一个指向新菜单的指针。 |
| setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopLeftCorner) | 在指定的角落放置一个小部件。 |
| clear() | 清除菜单栏上的所有菜单和分隔符。 |
| setNativeMenuBar(bool nativeMenuBar) | 设置是否使用本地菜单栏,如果为 true,则菜单栏将使用本地系统的菜单栏实现。 |
| setActiveAction(QAction *action) | 设置活动动作,该动作将在菜单栏上显示为活动状态。 |
| setCornerWidget(QWidget *widget, Qt::Corner corner = Qt::TopLeftCorner) | 在指定的角落放置一个小部件。 |

#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// ----------------------------------------------------------
// 堆代码 duidaima.com
// 创建菜单栏
// ----------------------------------------------------------
QMenuBar *bar = menuBar();
this->setMenuBar(bar); // 将菜单栏放入主窗口
QMenu * fileMenu = bar->addMenu("文件"); // 创建父节点
// 添加子菜单
QAction *newAction = fileMenu->addAction("新建文件"); // 设置名字
newAction->setIcon(QIcon("://image/file.ico")); // 设置可用图标
newAction->setShortcut(Qt::CTRL | Qt::Key_A); // 设置快捷键ctrl+a
fileMenu->addSeparator(); // 添加分割线
QAction *openAction = fileMenu->addAction("打开文件"); // 设置名字
openAction->setIcon(QIcon("://image/lock.ico")); // 设置可用图标
openAction->setShortcut(Qt::CTRL | Qt::Key_C); // 设置快捷键ctrl+c
// ----------------------------------------------------------
//创建工具栏 (可屏蔽掉 屏蔽掉后底部将失去控件栏位)
// ----------------------------------------------------------
QToolBar *toolBar = new QToolBar(this); // 创建工具栏
addToolBar(Qt::BottomToolBarArea,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);
// ----------------------------------------------------------
// 绑定槽函数
// ----------------------------------------------------------
connect(newAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发新建文件",QMessageBox::Ok);
});
connect(openAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发打开文件",QMessageBox::Ok);
});
}
由于通过connect绑定到了每一个Action上,所以当用户点击不同的菜单时将会触发不同的匿名槽函数,代码中实现了弹窗提示,此处也可以替换成任意代码,运行效果图如下所示;
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QMessageBox>
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/about.ico")); // 增加图标
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("设置文件内容");
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("读取文件内容");
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,"提示","触发编辑文件",QMessageBox::Ok);
});
connect(set_file,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发设置文件",QMessageBox::Ok);
});
connect(read_file,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发读取文件",QMessageBox::Ok);
});
}
代码运行后读者可看到如下图所示的效果,在配置模式中增加了两个子菜单,每个子菜单分别绑定到了一个槽函数上,而其父菜单仅仅只是展示功能此处可以不增加任何实质性的功能。
#include <iostream>
#include <QMenuBar>
#include <QToolBar>
#include <QCursor>
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 设置小部件(QWidget)的上下文菜单策略
this->setContextMenuPolicy(Qt::CustomContextMenu);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 触发右键创建菜单
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/about.ico"));
pEditTask->setIcon(QIcon(":/image/file.ico"));
pDeleteTask->setIcon(QIcon(":/image/lock.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;
}
接着就需要绑定到特定的槽函数上,用于接收用户点击的菜单选项,并根据选项做出相应的判断,这里我们定义一个onTaskBoxContextMenuEvent函数,并在MainWindow.h头文件进行声明,其实现部分如下所示;// 处理发送过来的信号
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:
QMessageBox::information(nullptr,"提示","触发新建任务",QMessageBox::Ok);
break;
case 2:
QMessageBox::information(nullptr,"提示","触发设置任务",QMessageBox::Ok);
break;
case 3:
QMessageBox::information(nullptr,"提示","触发删除任务",QMessageBox::Ok);
break;
default:
break;
}
}
至此当我们再次使用右键点击主页面时,则会弹出一个个性化菜单栏,如下图所示;
#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);
// ----------------------------------------------------------
// 创建menuBar组件
// ----------------------------------------------------------
// 创建基础顶部菜单并让其隐藏
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/about.ico"));
OpenAction->setIcon(QIcon(":/image/file.ico"));
ReadAction->setIcon(QIcon(":/image/lock.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);
// ----------------------------------------------------------
// 绑定槽函数
// ----------------------------------------------------------
connect(NewAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发新建文件按钮",QMessageBox::Ok);
});
connect(OpenAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发打开文件按钮",QMessageBox::Ok);
});
connect(ReadAction,&QAction::triggered,this,[=](){
QMessageBox::information(nullptr,"提示","触发读取文件按钮",QMessageBox::Ok);
});
}
运行后读者可看到如下图所示的案例,我们只保留了最基本的按钮栏,这样看起来更加的清爽。