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); }); }
运行后读者可看到如下图所示的案例,我们只保留了最基本的按钮栏,这样看起来更加的清爽。