QToolButton是一个 “带图标的按钮”
通过设置可以调整图标和文本的显示方式,如只显示图标、只显示文本、文本显示在图标旁边或下方等。
1. 效果演示
本案例展示如何设置工具按钮的样式表,并且实现页面切换的效果
2. 属性和方法
QToolButton有很多属性和方法,完整的可查看帮助文档。这里列出常用的属性和方法:
2.1 设置图标和文本
void setIcon(const QIcon &icon); // 设置图标
void setIconSize(const QSize &size); // 设置图标大小
void setText(const QString &text); // 设置文本
void setToolButtonStyle(Qt::ToolButtonStyle style); // 设置按钮风格
其中,Qt::ToolButtonStyle是一个枚举,可取的值如下:
| 枚举 | 值 | 含义 |
|---|---|---|
| Qt::ToolButtonIconOnly | 0 | 只显示图标 |
| Qt::ToolButtonTextOnly | 1 | 只显示文字 |
| Qt::ToolButtonTextBesideIcon | 2 | 文本在图标一侧 |
| Qt::ToolButtonTextUnderIcon | 3 | 文本在图标下方 |
2.2 设置菜单
// 设置弹出菜单, 以及弹出菜单模式
void setMenu(QMenu* menu);
void setPopupMode(ToolButtonPopupMode mode);
ToolButton提供了三种弹出菜单模式:
- DelayedPopup
默认模式,长按按钮后延迟弹出菜单。这通常用于需要用户长按以确认操作的场景。 - MenuButtonPopup
点击按钮箭头图标后立即弹出菜单。这种模式下,工具按钮显示一个特殊的箭头以指示菜单的存在。 - InstantPopup
点击按钮时立即弹出菜单,无延迟。这种模式下,按钮自身的动作不触发,而是直接显示菜单。
2.3 信号槽
// 当按钮被点击时发出该信号。如果是可选中的按钮,checked 参数将指示按钮是否被选中。
void clicked(bool checked = false)
// 当其选中状态改变时发出该信号
void toggled(bool checked)
// 当与按钮关联的下拉菜单中的某个动作被触发时发出该信号
void triggered(QAction *action)
3. 从零实现
从零写代码实现整体效果,以演示工具按钮的属性以及信号槽的用法
3.1 布局
在UI设计师界面,拖拽对应的控件,修改显示的文字、控件的名称,然后完成布局
- 最顶层的
MyWidget采用水平布局,左侧是leftWidget,右侧是stackedWidget,并将MyWidget布局的边距和间隙都设置为0 - 设置
leftWidget的背景色为rgb(220, 240, 255),stackedWidget的背景色为rgb(235, 245, 255) - 修改
ToolButton的属性:toolButtonStyle设置为ToolButtonTextUnderIconicon属性中,选择一个系统图标,并将iconSize设置为64*64text设置为 “演示文本”,font的Point Size设置为16
布局完成效果如下:
3.2 添加资源文件
把用到的图标,作为资源文件添加到项目中,如下:
3.3 代码实现
3.3.1 工具按钮样式表
首先,为了保证10个工具按钮可以互斥地选中,在mywidget.h中声明一个按钮组,如下:
#include <QButtonGroup>
class MyWidget : public QWidget {
private:
QButtonGroup *btnGroup;
};
然后,循环地设置工具按钮的属性和样式表,如下:
MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {
this->setWindowTitle("明王讲QT | 第二章 常用控件 | 2.11 工具按钮QToolButton (WX: coding4096)");
// 左侧设置一个最大宽度
ui->leftWidget->setMaximumWidth(250);
// clang-format off
// 工具按钮的文字
QStringList names; // 按钮文字集合
names << "基础组件" << "图标字体" << "高级组件" << "图表(官方)" << "图表(三方)"
<< "仪表盘" << "语法高亮" << "天气预报" << "精美换肤" << "未完待续...";
// 工具按钮的图标
QStringList icons;
icons << ":/res/base.png"
<< ":/res/iconfont.png"
<< ":/res/advance.png"
<< ":/res/chart.png"
<< ":/res/customplot.png"
<< ":/res/gauge.png"
<< ":/res/hilight.png"
<< ":/res/weather.png"
<< ":/res/skin.png"
<< ":/res/more.png";
// 工具按钮
QList<QToolButton*> toolBtns;
toolBtns << ui->toolBtnBasic
<< ui->toolBtnIcon
<< ui->toolBtnAdvance
<< ui->toolBtnQChart
<< ui->toolBtnQCustomPlot
<< ui->toolBtnGauge
<< ui->toolBtnHighlight
<< ui->toolBtnWeather
<< ui->toolBtnSkin
<< ui->toolBtnMore;
btnGroup = new QButtonGroup(this);
// clang-format on
for (int i = 0; i < names.count(); i++) {
// 设置样式、大小策略
toolBtns[i]->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
toolBtns[i]->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
// 设置文字
toolBtns[i]->setText(QString("%1").arg(names.at(i)));
// 设置图标
QPixmap pix = QPixmap(icons[i]);
toolBtns[i]->setIcon(QIcon(pix));
toolBtns[i]->setIconSize(QSize(64, 64));
//设置按钮可选中-按下类似复选框的功能
toolBtns[i]->setCheckable(true);
// 设置按钮的样式
toolBtns[i]->setStyleSheet(R"(
QToolButton {
border:1px solid #A0A0A0;
font:18px "Microsoft YaHei";
color:#386487;
padding:5px;
border-radius:5px;
background: #DEF0FE;
}
QToolButton:hover {
background:#C0DEF5;
}
QToolButton:checked {
background:#C0DEF5;
}
)");
// 将按钮添加到 btnGroup
btnGroup->addButton(toolBtns[i], i);
}
}
此时,运行效果:
3.3.2 添加10个页面
首先,添加一个C++类,让它继承自QWidget,并在页面的构造中添加一个标签,如下:
然后,继续添加剩余的9个页面,可以按照上边的方法,继续添加
也可以直接复制文件,并修改对应的文件名和类名,以及
CMakeList.txt文件
10个页面添加完成后,效果如下:
3.3.3 页面切换
首先,在mywidget.cpp中为stackedWidget中添加10个页面,如下:
#include "advance_widget.h"
#include "basic_widget.h"
#include "chart_widget.h"
#include "customplot_widget.h"
#include "gauge_widget.h"
#include "highlight_widget.h"
#include "icon_widget.h"
#include "more_widget.h"
#include "skin_widget.h"
#include "weather_widget.h"
MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {
// ...
ui->stackedWidget->addWidget(new BasicWidget());
ui->stackedWidget->addWidget(new IconWidget());
ui->stackedWidget->addWidget(new AdvanceWidget());
ui->stackedWidget->addWidget(new ChartWidget());
ui->stackedWidget->addWidget(new CustomplotWidget());
ui->stackedWidget->addWidget(new GaugeWidget());
ui->stackedWidget->addWidget(new HighlightWidget());
ui->stackedWidget->addWidget(new WeatherWidget());
ui->stackedWidget->addWidget(new SkinWidget());
ui->stackedWidget->addWidget(new MoreWidget());
}
然后,在mywidget.h/mywidget.cpp中,声明、关联、实现信号槽,如下:
// mywidget.h
class MyWidget : public QWidget {
private slots:
void onBtnGroupClicked(int id);
};
// mywidget.cpp
class MyWidget : public QWidget {
// ...
for (int i = 0; i < names.count(); i++) {
// ...
// 关联信号槽
connect(btnGroup, &QButtonGroup::idClicked, this, &MyWidget::onBtnGroupClicked);
}
}
void MyWidget::buttonClicked() {
stackedWidget->setCurrentIndex(btnGroup->checkedId());
}
最后,在mywidget.cpp中,默认选中第一个工具按钮,如下:
MyWidget::MyWidget(QWidget* parent) : QWidget(parent), ui(new Ui::MyWidget) {
// ...
ui->toolBtnBasic->click();
}
4. 点赞、获取源码
看到这里的小伙伴,去B站给明王一个【免费的点赞】吧,你的支持,是我持续更新优质内容的动力,感谢~
源码下载地址
链接: https://pan.baidu.com/s/1OwqKHh_o5kRYofprjHY3xA
提取码: ming







