QtQt控件Qt中按钮类型的控件
苏丙榅文章中主要介绍了Qt中常用的按钮控件, 包括: QAbstractButton
, QPushButton
, QToolButton
, QRadioButton
, QCheckBox
。 关于这些控件的使用除了文字描述、代码演示, 还有相关的视频讲解,赶紧给自己充电吧…
在QT中为我们提供了可以直接使用的按钮控件, 如下图。这些按钮种类虽然繁多, 但是它们都拥有相同的父类 QAbstractButton
。这些子类按钮的大部分属性都是从这个基类继承的,因此搞明白这个类为我们提供的相关功能还是非常重要的。
其中Dialog Button Box
比较特殊不是一个单一控件, 它是两个QPushButton
的组合并且水平排列, 这个不能作为一个新控件来研究。
这些按钮控件之间的继承关系如下图:
下边从功能的视角, 给大家介绍一下QAbstractButton
中的一些常用API
1.1 标题和图标
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| void QAbstractButton::setText(const QString &text);
QString QAbstractButton::text() const;
QIcon icon() const;
void setIcon(const QIcon &icon);
QSize iconSize() const
[slot]void setIconSize(const QSize &size);
|
1.2 按钮的 Check
属性
对应按钮来说, 一般有三种常见状态, 分别为: Normal
, Hover
, Pressed
。
Normal
: 普通状态, 没有和鼠标做任何接触
Hover
: 悬停状态, 鼠标位于按钮之上, 但是并未按下
Pressed
: 按压状态, 鼠标键在按钮上处于按下状态
默认情况下, 鼠标在按钮上按下, 按钮从 Normal
切换到 Pressed
状态, 鼠标释放, 按钮从 Pressed
恢复到Normal
状态。
当我们给按钮设置了 check
属性之后,情况就有所不同了, 在按钮上释放鼠标键, 按钮依然会处在 Pressed
状态, 再次点击按钮, 按钮才能恢复到 Normal
状态。具有check
属性的按钮就相当于一个开关, 每点击一次才能实现一次状态的切换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
bool QAbstractButton::isCheckable() const;
void QAbstractButton::setCheckable(bool);
bool QAbstractButton::isChecked() const;
void QAbstractButton::setChecked(bool);
|
1.3 信号
这些信号都按钮被点击之后发射出来的, 只是在细节上有细微的区别, 其中最常用的是 clicked()
, 通过鼠标的不同瞬间状态可以发射出pressed()
和 released()
信号, 如果鼠标设置了 check
属性, 一般通过 toggled()
信号判断当前按钮是选中状态还是非选中状态。
1 2 3 4 5 6 7 8 9 10
|
[signal] void QAbstractButton::clicked(bool checked = false);
[signal] void QAbstractButton::pressed();
[signal] void QAbstractButton::released();
[signal] void QAbstractButton::toggled(bool checked);
|
1.4 槽函数
1 2 3 4 5 6 7 8 9 10 11
| [slot] void QAbstractButton::animateClick(int msec = 100);
[slot] void QAbstractButton::click();
[slot] void QAbstractButton::setChecked(bool);
[slot]void setIconSize(const QSize &size);
[slot] void QAbstractButton::toggle();
|
了解了基类提供的功能之后, 下边着重给大家介绍一下按钮组中常用的几这个按钮控件: QPushButton
, QToolButton
, QRadioButton
, QCheckBox
。
2.1 常用API
这种类型的按钮是Qt按钮中使用频率最高的一个, 对这个类进行操作, 大部分时候都需要使用它从父类继承过来的那些 API。
在QPushButton
类中, 比较常用的一些API函数如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
QPushButton::QPushButton(const QIcon &icon, const QString &text, QWidget *parent = nullptr); QPushButton::QPushButton(const QString &text, QWidget *parent = nullptr); QPushButton::QPushButton(QWidget *parent = nullptr);
bool isDefault() const;
void setDefault(bool);
void QPushButton::setMenu(QMenu *menu);
[slot] void QPushButton::showMenu();
|
2.2 按钮的使用
通过API的介绍, 我们可以知道, 使用QPushButton
这种类型的按钮, 有三种使用方式:
作为普通按钮, 可以显示文本信息和图标
设置check属性, 使其可以处于持续的被选中状态
关联一个菜单, 点击按钮菜单弹出
具体操作可以参考如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this);
ui->normalBtn->setText("我是小猪佩奇"); ui->normalBtn->setIcon(QIcon(":/Peppa-Pig.png")); ui->normalBtn->setIconSize(QSize(30, 30)); connect(ui->normalBtn, &QPushButton::clicked, this, [=]() { qDebug() << "我是一个普通按钮, 图标是小猪佩奇..."; });
ui->checkedBtn->setCheckable(true); connect(ui->checkedBtn, &QPushButton::toggled, this, [=](bool bl) { qDebug() << "我是一个checked按钮, 当前状态为:" << bl; });
ui->menuBtn->setText("你喜欢哪种美女?"); QMenu* menu = new QMenu; QAction* act = menu->addAction("可爱的"); menu->addAction("粘人的"); menu->addAction("胸大的"); menu->addAction("屁股翘的"); ui->menuBtn->setMenu(menu); connect(act, &QAction::triggered, this, [=]{ qDebug() << "我是一个可爱的女人, 今晚约吗?"; }); }
|
3.1 常用API
这个类也是一个常用按钮类, 使用方法和功能跟QPushButton
基本一致, 只不过在对于关联菜单这个功能点上, QToolButton
类可以设置弹出的菜单的属性, 以及在显示图标的时候可以设置更多的样式, 可以理解为是一个增强版的QPushButton
。
和QPushButton
类相同的是, 操作这个按钮使用的大部分函数都是从父类QAbstractButton
继承过来的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| QToolButton::QToolButton(QWidget *parent = nullptr);
void QToolButton::setMenu(QMenu *menu);
QMenu *QToolButton::menu() const;
void setPopupMode(QToolButton::ToolButtonPopupMode mode);
QToolButton::ToolButtonPopupMode popupMode() const;
void setArrowType(Qt::ArrowType type);
Qt::ArrowType arrowType() const;
[slot] void QToolButton::setDefaultAction(QAction *action);
QAction *QToolButton::defaultAction() const;
[slot] void QToolButton::setToolButtonStyle(Qt::ToolButtonStyle style);
Qt::ToolButtonStyle toolButtonStyle() const;
[slot] void QToolButton::showMenu();
|
3.2 按钮的使用
通过API的介绍, 我们可以知道, 使用QToolButton
这种类型的按钮, 有三种使用方式:
作为普通按钮, 可以显示文本信息和图标
按钮的图标可以使用不同的方式设置, 并且制定图标和文本信息的显示模式
设置check属性, 使其可以处于持续的被选中状态
关联一个菜单, 点击按钮菜单弹出, 并且可以设置菜单的弹出方式
具体操作可以参考如下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this);
ui->normalBtn->setText("我是个屌丝"); ui->normalBtn->setIconSize(QSize(50, 50)); ui->normalBtn->setIcon(QIcon(":/mario.png")); connect(ui->normalBtn, &QToolButton::clicked, this, [=]() { qDebug() << "我是一个普通按钮, 是一个屌丝..."; }); ui->normalBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); QAction* actBtn = new QAction(QIcon(":/mushroom_life.png"), "奥利给"); ui->actionBtn->setDefaultAction(actBtn); connect(ui->actionBtn, &QToolButton::triggered, this, [=](QAction* act) { act->setText("我是修改之后的马里奥..."); act->setIcon(QIcon(":/mario.png")); }); ui->actionBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); ui->arrowBtn->setArrowType(Qt::UpArrow); ui->arrowBtn->setText("向上"); ui->arrowBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
ui->checkedBtn->setCheckable(true); connect(ui->checkedBtn, &QToolButton::toggled, this, [=](bool bl) { qDebug() << "我是一个checked按钮, 当前状态为:" << bl; });
ui->menuBtn->setText("你喜欢哪种美女?"); QMenu* menu = new QMenu; QAction* act = menu->addAction("可爱的"); menu->addAction("粘人的"); menu->addAction("胸大的"); menu->addAction("屁股翘的"); ui->menuBtn->setMenu(menu); connect(act, &QAction::triggered, this, [=]{ qDebug() << "我是一个可爱的女人, 今晚约吗?"; });
ui->popmenu->setMenu(menu);
ui->popmenu->setPopupMode(QToolButton::MenuButtonPopup); connect(ui->popmenu, &QToolButton::clicked, this, [=]() { qDebug() << "我是popMenu按钮, 好痒呀..."; }); }
|
QRadioButton
是Qt提供的单选按钮, 一般都是以组的方式来使用(多个按钮中同时只能选中其中一个
)。操作这个按钮使用的大部分函数都是从父类继承过来的, 它的父类是QAbstractButton
。
关于单选按钮的使用我们还需要注意一点, 如果单选按钮被选中, 再次点击这个按钮选中状态是不能被取消的。
4.1 常用API
这个类混的很失败, 一直生活在父类的阴影之下, 也没有什么作为, 在官方的帮助文档中, 处理构造函数就没有再提供其他可用的 API了
1 2 3 4 5 6 7 8
|
QRadioButton::QRadioButton(const QString &text, QWidget *parent = nullptr); QRadioButton::QRadioButton(QWidget *parent = nullptr);
|
4.2 按钮的使用
单选按钮一般是以组的形式来使用的, 如果在一个窗口中需要有多个单选按钮组, 应该如何处理呢?
在同一窗口中, Qt会认为所有的单选按钮都属于同一组, 如果需要多个单选按钮组, 应该将他们放到不同的子窗口中。
通过上图可以看到有两个单选按钮组, 在制作的时候分别将单选按钮放到了不同的容器窗口(组框)中,这样就被人为分隔为两组了。
如果我们使用鼠标点击了某个单选按钮, 按钮还是会发射出 clicked()
信号, 简单的按钮测试代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void MainWindow::on_redio_996_clicked() { qDebug() << "996"; }
void MainWindow::on_radio_nosalary_clicked() { qDebug() << "没有加班费"; }
void MainWindow::on_radio_nogirl_clicked() { qDebug() << "公司没有妹子..."; }
void MainWindow::on_radio_notbeautiful_clicked(bool checked) { qDebug() << "前台小姐姐不好看!!!"; }
|
5. QCheckBox
QCheckBox是Qt中的复选框按钮, 可以单独使用, 也可以以组的方式使用(同一组可以同时选中多个), 当复选按钮被选中, 再次点击之后可以取消选中状态, 这一点和单选按钮是不同的。
操作这个按钮使用的大部分函数都是从父类继承过来的, 它的父类是QAbstractButton
。
5.1 常用API
我们对复选框按钮操作的时候, 可以设置选中和未选中状态, 并且还可以设置半选中状态, 这种半选中状态一般需要当前复选框按钮下还有子节点, 类似一树状结构。
公共成员函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
QCheckBox::QCheckBox(const QString &text, QWidget *parent = nullptr); QCheckBox::QCheckBox(QWidget *parent = nullptr);
bool isTristate() const;
void setTristate(bool y = true);
void QCheckBox::setCheckState(Qt::CheckState state);
Qt::CheckState QCheckBox::checkState() const;
|
信号
1 2 3
|
[signal] void QCheckBox::stateChanged(int state);
|
5.2 按钮的使用
下面针对于复选框按钮的三种状态, 为大家展示一下对应的操作流程, 首先第一步搭建一个有树状关系的界面:
这些复选框按钮的关系以及 objectName
如下:
第二步, 在窗口类的头文件中添加槽函数, 槽函数处理复选框按钮的状态变化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE
class MainWindow : public QMainWindow { Q_OBJECT
public: MainWindow(QWidget *parent = nullptr); ~MainWindow();
private slots: void statusChanged(int state);
private: Ui::MainWindow *ui; int m_number = 0; };
|
第三步, 在源文件中添加处理逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this);
ui->wives->setTristate(true); connect(ui->wives, &QCheckBox::clicked, this, [=](bool bl) { if(bl) { ui->jianning->setChecked(true); ui->fangyi->setChecked(true); ui->longer->setChecked(true); ui->zengrou->setChecked(true); ui->mujianping->setChecked(true); ui->shuanger->setChecked(true); ui->ake->setChecked(true); } else { ui->jianning->setChecked(false); ui->fangyi->setChecked(false); ui->longer->setChecked(false); ui->zengrou->setChecked(false); ui->mujianping->setChecked(false); ui->shuanger->setChecked(false); ui->ake->setChecked(false); } });
connect(ui->jianning, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); connect(ui->fangyi, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); connect(ui->longer, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); connect(ui->zengrou, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); connect(ui->mujianping, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); connect(ui->shuanger, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); connect(ui->ake, &QCheckBox::stateChanged, this, &MainWindow::statusChanged); }
void MainWindow::statusChanged(int state) { if(state == Qt::Checked) { m_number ++; } else { m_number --; }
if(m_number == 7) { ui->wives->setCheckState(Qt::Checked); } else if(m_number == 0) { ui->wives->setCheckState(Qt::Unchecked); } else { ui->wives->setCheckState(Qt::PartiallyChecked); } }
|
最终效果展示:
6. 视频讲解
以上知识点对应的视频讲解可以关注 B站-爱编程的大丙
视频地址: https://www.bilibili.com/video/BV1ff4y1C7CK