Qt Widgets 之 Button
本文介绍了Qt中常用的按钮控件及其使用方法。文章首先指出Qt中的按钮都是基于QAbstractButton抽象基类的实现,并提供了四种主要按钮类型的对比表格:QPushButton(命令按钮)、QToolButton(工具按钮)、QRadioButton(单选按钮)和QCheckBox(复选框)。 文章重点介绍了QPushButton和QToolButton的使用方法。对于QPushButton,
Qt 中提供的按钮,都是抽象基类 QAbstractButton 的实现。
想要简单了解这些按钮的通用的功能,可以翻阅这篇: Qt Widgets 之 QAbstractButton
一、概述
Qt 自带的按钮控件应对不同的场景需求,主要有:
| 按钮类型 | 类名 | 特点 | 适用场景 |
|---|---|---|---|
| 命令按钮 | QPushButton | 最常用的按钮类型,执行即时操作 | 大多数需要触发操作的场景 |
| 工具按钮 | QToolButton | 工具栏上的专用按钮,支持多种显示样式,可带弹出菜单 | 工具栏、小型操作按钮 |
| 单选按钮 | QRadioButton | 从多个选项中选择一个 | 设置选项,互斥选择 |
| 复选框 | QCheckBox | 开关选项或多项选择, 支持三态(选中/未选中/部分选中) |
启用/禁用功能,多项选择 |
关于按钮在Qt模块的继承关系如图所示:
二、QPushButton(命令按钮)
QPushButton 是 Qt 中最常用的按钮控件,通常用于点击触发操作,也可以采用按下、释放触发。
主要有以下特性:
- 支持文本和图标显示
- 可以设置为默认按钮(对话框中按Enter键触发的按钮)
- 支持可选中(toggle)行为
- 支持自动重复功能
构造及基本用法
#include <QPushButton>
// 创建按钮
// 方式1: 直接创建并设置父对象
QPushButton* button1 = new QPushButton(parentWidget);
// 方式2: 创建时指定文本
QPushButton* button2 = new QPushButton("Click Me", parentWidget);
// 方式3: 创建时指定图标和文本
QPushButton* button3 = new QPushButton(QIcon(":/images/icon.png"), "Click Me", parentWidget);
// 设置图标
button->setIcon(QIcon(":/images/icon.png"));
button->setIconSize(QSize(32, 32));
// 设置按钮属性
button->setEnabled(true); // 启用按钮,禁用为false,按钮变灰
button->setChecked(true); // 设置选中状态,按钮高亮
button->setDefault(true); // 设置为默认按钮(回车键触发)
button->setFlat(false); // 设置为非扁平样式(默认有3D效果)
其他用法
-
void setDefault(bool enabled)
设置按钮是否为默认按钮。默认按钮在对话框中通常有特殊外观,并响应Enter键。 -
bool isDefault() const
返回按钮是否为默认按钮。 -
void setAutoDefault(bool enabled)
设置按钮是否自动成为默认按钮。当设置为true时,按钮在获得焦点时会自动成为默认按钮。 -
bool autoDefault() const
返回按钮是否自动成为默认按钮。
信号连接
QPushButton 自带多个信号来触发响应用户交互。
常用信号有:
-
按钮被点击时发出(最常用)
void clicked(bool checked = false); -
按钮被按下时发出
void pressed(); -
按钮被释放时发出
void released(); -
可选中按钮状态改变时发出
void toggled(bool checked);
信号连接示例:
// 连接clicked信号(最常用)
connect(button, &QPushButton::clicked, this, &MyClass::onButtonClicked);
// 使用lambda表达式
connect(button, &QPushButton::clicked, [=]() {
qDebug() << "Button clicked!";
});
// 可检查按钮的状态变化
button->setCheckable(true); // 设置为可检查
connect(button, &QPushButton::toggled, [=](bool checked) {
qDebug() << "Button state:" << (checked ? "Checked" : "Unchecked");
});
样式表示例
// 基本样式
button->setStyleSheet(
"QPushButton {"
" background-color: #4CAF50;"
" border: none;"
" color: white;"
" padding: 10px 20px;"
" border-radius: 8px;"
"}"
"QPushButton:hover {"
" background-color: #45a049;"
"}"
"QPushButton:pressed {"
" background-color: #3d8b40;"
"}"
"QPushButton:disabled {"
" background-color: #cccccc;"
" color: #666666;"
"}"
"QPushButton:checked {" // 针对可检查按钮的选中状态
" background-color: #2196F3;"
"}"
);
三、QToolButton(工具按钮)
QToolButton是工具按钮控件,通常用于工具栏中,比如软件的“File”,“about” 等按钮,提供了工具按钮的特有功能,如弹出菜单和各种显示模式。
主要特性:
- 通常用于工具栏中
- 支持各种显示模式(只显示图标、只显示文本等)
- 支持弹出菜单
- 可以设置为自动提升(只在鼠标悬停时显示3D效果)
构造及基本用法
#include <QToolButton>
#include <QMenu>
// 创建工具按钮
QToolButton *toolButton = new QToolButton(parentWidget);
// 设置图标
toolButton->setIcon(QIcon(":/images/tool.png"));
// 设置显示样式
toolButton->setToolButtonStyle(Qt::ToolButtonIconOnly); // 只显示图标
// 可选样式:
// Qt::ToolButtonIconOnly - 只显示图标
// Qt::ToolButtonTextOnly - 只显示文本
// Qt::ToolButtonTextBesideIcon - 文本在图标旁边
// Qt::ToolButtonTextUnderIcon - 文本在图标下方
// Qt::ToolButtonFollowStyle - 跟随应用程序风格
// 下拉菜单
// 创建弹出菜单
QMenu *menu = new QMenu(&window);
menu->addAction("Action 1");
menu->addAction("Action 2");
menu->addAction("Action 3");
// 设置弹出菜单
toolButton->setMenu(menu);
toolButton->setPopupMode(QToolButton::MenuButtonPopup); // 带菜单箭头的按钮
其他用法
-
void setToolButtonStyle(Qt::ToolButtonStyle style)
设置工具按钮的显示风格。 -
Qt::ToolButtonStyle toolButtonStyle() const
返回工具按钮的显示风格。 -
void setAutoRaise(bool enable)
设置是否自动提升(只在鼠标悬停时显示3D效果)。 -
bool autoRaise() const
返回是否自动提升。 -
void setPopupMode(QToolButton::ToolButtonPopupMode mode)
设置弹出菜单的模式。 -
QToolButton::ToolButtonPopupMode popupMode() const
返回弹出菜单的模式。 -
void setMenu(QMenu *menu)
设置弹出菜单。 -
QMenu *menu() const
返回弹出菜单。
样式表示例
toolButton->setStyleSheet(
"QToolButton {"
" background-color: #f0f0f0;"
" border: 1px solid #cccccc;"
" border-radius: 4px;"
" padding: 5px;"
"}"
"QToolButton:hover {"
" background-color: #e0e0e0;"
"}"
"QToolButton:pressed {"
" background-color: #d0d0d0;"
"}"
"QToolButton::menu-button {"
" width: 20px;"
" border-left: 1px solid #cccccc;"
"}"
);
四、QRadioButton(单选按钮)
QRadioButton是单选按钮控件,允许用户从多个选项中选择一个,通常需要与QButtonGroup一起使用以实现互斥选择。
主要特性:
- 支持单选功能(同一组内互斥)
- 适合单项选择场景
- 默认具有自动排他性(同父组件的单选按钮自动互斥)
基本用法
#include <QRadioButton>
#include <QButtonGroup>
// 创建单选按钮
QRadioButton *radio1 = new QRadioButton("Option 1", parentWidget);
QRadioButton *radio2 = new QRadioButton("Option 2", parentWidget);
QRadioButton *radio3 = new QRadioButton("Option 3", parentWidget);
// 设置默认选中
radio1->setChecked(true);
// 方法一:使用按钮组管理互斥行为(推荐)
QButtonGroup *buttonGroup = new QButtonGroup(parentWidget);
buttonGroup->addButton(radio1);
buttonGroup->addButton(radio2);
buttonGroup->addButton(radio3);
buttonGroup->setExclusive(true); // 确保只能选中一个
// 方法二:默认同一父组件下,就是互斥的,无需额外设置
// 获取选中的按钮
QRadioButton *selectedRadio = qobject_cast<QRadioButton*>(buttonGroup->checkedButton());
if (selectedRadio) {
qDebug() << "Selected:" << selectedRadio->text();
}
信号连接
// 单个按钮的状态变化
connect(radio1, &QRadioButton::toggled, [=](bool checked) {
if (checked) {
qDebug() << "Radio 1 selected";
}
});
// 按钮组的信号
connect(buttonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
[=](QAbstractButton *button) {
qDebug() << "Button clicked:" << button->text();
});
样式表示例
radio1->setStyleSheet(
"QRadioButton {"
" spacing: 5px;" // 文本和指示器之间的间距
" color: #333333;"
" font-size: 14px;"
"}"
"QRadioButton::indicator {"
" width: 16px;"
" height: 16px;"
"}"
"QRadioButton::indicator:unchecked {"
" border: 2px solid #999999;"
" border-radius: 8px;"
" background-color: white;"
"}"
"QRadioButton::indicator:checked {"
" border: 2px solid #2196F3;"
" border-radius: 8px;"
" background-color: #2196F3;"
"}"
);
五、QCheckBox(复选框)
QCheckBox是复选框控件,允许用户选择多个选项,提供了复选框的特有功能。
主要特性:
- 支持两种状态(选中/未选中)或三种状态(选中/部分选中/未选中)
- 适合多项选择场景
- 可以分组使用,但不互斥(与QRadioButton不同)
基本用法
#include <QCheckBox>
// 创建复选框
QCheckBox *checkBox = new QCheckBox("Enable feature", parentWidget);
// 设置三态支持(可选)
checkBox->setTristate(true); // 启用三态
// 设置检查状态
checkBox->setCheckState(Qt::Checked); // 2 完全选中
// 其他状态:
// Qt::Unchecked - 0 未选中
// Qt::PartiallyChecked - 1 部分选中
// 获取状态
// Qt::CheckState state = checkBox->checkState();
if (checkBox->checkState() == Qt::Checked) {
qDebug() << "Checkbox is checked";
}
其他方法:
-
void setTristate(bool y = true)
设置复选框是否支持三态模式。 -
bool isTristate() const
返回复选框是否支持三态模式。 -
void setCheckState(Qt::CheckState state)
设置复选框的状态(包括三态)。 -
Qt::CheckState checkState() const
返回复选框的当前状态(包括三态)。
信号连接
// 状态变化信号
connect(checkBox, &QCheckBox::stateChanged, [=](int state) {
if (state == Qt::Checked) {
qDebug() << "Checked";
} else if (state == Qt::Unchecked) {
qDebug() << "Unchecked";
} else if (state == Qt::PartiallyChecked) {
qDebug() << "Partially checked";
}
});
样式表示例
checkBox->setStyleSheet(
"QCheckBox {"
" spacing: 5px;"
" color: #333333;"
" font-size: 14px;"
"}"
"QCheckBox::indicator {"
" width: 16px;"
" height: 16px;"
"}"
"QCheckBox::indicator:unchecked {"
" border: 2px solid #999999;"
" background-color: white;"
"}"
"QCheckBox::indicator:checked {"
" border: 2px solid #2196F3;"
" background-color: #2196F3;"
"}"
"QCheckBox::indicator:indeterminate {" // 部分选中状态
" border: 2px solid #2196F3;"
" background-color: #90CAF9;"
"}"
);
七、经验与实践
1. 按钮分组管理
// 创建按钮组
QButtonGroup *buttonGroup = new QButtonGroup(parentWidget);
// 添加按钮到组中
buttonGroup->addButton(radio1);
buttonGroup->addButton(radio2);
buttonGroup->addButton(checkBox); // 也可以混合不同类型
// 设置互斥性(默认情况下,QRadioButton会自动互斥)
buttonGroup->setExclusive(true); // 设置组内按钮互斥
// 连接组信号
connect(buttonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked),
[=](QAbstractButton *button) {
qDebug() << "Button in group clicked:" << button->text();
});
2. 动态按钮创建
// 动态创建多个按钮
QList<QPushButton*> buttons;
for (int i = 0; i < 5; ++i) {
QPushButton *btn = new QPushButton(QString("Button %1").arg(i+1), parentWidget);
connect(btn, &QPushButton::clicked, [=]() {
handleButtonClick(i);
});
buttons.append(btn);
}
3. 设置快捷键
// 方式一:设置快捷键
button->setShortcut(QKeySequence("Ctrl+S")); // Ctrl+S触发按钮
button->setShortcut(Qt::Key_Return); // 回车键触发按钮
// 方式二:使用"&"符号在文本中指定快捷键(Alt+字母)
button->setText("&Save"); // Alt+S触发按钮
QPushButton *button = new QPushButton("&Save", this); // Alt+S
// 方法3:使用QAction关联快捷键
QAction *saveAction = new QAction("Save", this);
saveAction->setShortcut(QKeySequence::Save);
connect(saveAction, &QAction::triggered, this, &MainWindow::save);
button->addAction(saveAction);
4. 设置辅助功能
设置辅助功能属性,主要针对于视障人士会用到屏幕阅读器,这个功能就会被用到。
button->setAccessibleName("Save Button");
button->setAccessibleDescription("Saves the current document");
5. 自定义按钮绘制
class CustomButton : public QPushButton {
Q_OBJECT
public:
explicit CustomButton(QWidget* parent = nullptr)
: QPushButton(parent) {
// 自定义初始化
}
protected:
void paintEvent(QPaintEvent *event) override {
QPainter painter(this);
// 自定义绘制代码
painter.setRenderHint(QPainter::Antialiasing);
// 绘制背景
painter.setBrush(QColor("#2196F3"));
painter.drawRoundedRect(rect(), 10, 10);
// 绘制文本
painter.setPen(Qt::white);
painter.drawText(rect(), Qt::AlignCenter, text());
}
};
八、常见问题与解决方案
-
按钮点击无响应
- 检查按钮是否被禁用(
setEnabled(false)或者isEnabled()返回false) - 确认信号槽连接是否正确
- 检查是否有其他控件覆盖了按钮
- 检查事件过滤器是否阻止了事件传递
- 检查父组件是否拦截了事件
- 检查按钮是否被禁用(
-
样式表不生效
- 确保样式表语法正确
- 检查选择器是否正确匹配按钮类型
- 确认样式表特异性足够(使用更具体的选择器)
-
国际化支持
// 对所有用户可见文本使用tr()函数包装 QPushButton *button = new QPushButton(tr("Click Me"), parentWidget); QCheckBox *checkBox = new QCheckBox(tr("Enable feature"), parentWidget); button->setText(tr("Save")); -
内存管理
- 始终为按钮设置父对象,以便自动内存管理。若没有设置父对象,则需要
delete - 使用QPointer跟踪按钮指针,避免悬空指针。
- 始终为按钮设置父对象,以便自动内存管理。若没有设置父对象,则需要
-
布局管理
- 最好将将按钮添加到布局中,不使用绝对坐标。
持续更新中。。。。
更多推荐


所有评论(0)