QtQt控件Qt中按钮类型的控件
苏丙榅文章中主要介绍了Qt中常用的按钮控件, 包括: QAbstractButton, QPushButton, QToolButton, QRadioButton, QCheckBox。 关于这些控件的使用除了文字描述、代码演示, 还有相关的视频讲解,赶紧给自己充电吧…
在QT中为我们提供了可以直接使用的按钮控件, 如下图。这些按钮种类虽然繁多, 但是它们都拥有相同的父类 QAbstractButton。这些子类按钮的大部分属性都是从这个基类继承的,因此搞明白这个类为我们提供的相关功能还是非常重要的。
其中Dialog Button Box比较特殊不是一个单一控件, 它是两个QPushButton的组合并且水平排列, 这个不能作为一个新控件来研究。
    
这些按钮控件之间的继承关系如下图:
 
下边从功能的视角, 给大家介绍一下QAbstractButton中的一些常用API
1.1 标题和图标
| 12
 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属性的按钮就相当于一个开关, 每点击一次才能实现一次状态的切换。
| 12
 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()信号判断当前按钮是选中状态还是非选中状态。
| 12
 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 槽函数
| 12
 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函数如下:
| 12
 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属性, 使其可以处于持续的被选中状态
- 关联一个菜单, 点击按钮菜单弹出
具体操作可以参考如下代码:
| 12
 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继承过来的。
| 12
 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属性, 使其可以处于持续的被选中状态
- 关联一个菜单, 点击按钮菜单弹出, 并且可以设置菜单的弹出方式
具体操作可以参考如下代码:
| 12
 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了
| 12
 3
 4
 5
 6
 7
 8
 
 | 
 
 
 
 
 QRadioButton::QRadioButton(const QString &text, QWidget *parent = nullptr);
 QRadioButton::QRadioButton(QWidget *parent = nullptr);
 
 | 
4.2 按钮的使用
单选按钮一般是以组的形式来使用的, 如果在一个窗口中需要有多个单选按钮组, 应该如何处理呢?
在同一窗口中, Qt会认为所有的单选按钮都属于同一组, 如果需要多个单选按钮组, 应该将他们放到不同的子窗口中。
   
通过上图可以看到有两个单选按钮组, 在制作的时候分别将单选按钮放到了不同的容器窗口(组框)中,这样就被人为分隔为两组了。
 
如果我们使用鼠标点击了某个单选按钮, 按钮还是会发射出 clicked()信号, 简单的按钮测试代码如下所示:
| 12
 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
我们对复选框按钮操作的时候, 可以设置选中和未选中状态, 并且还可以设置半选中状态, 这种半选中状态一般需要当前复选框按钮下还有子节点, 类似一树状结构。
- 公共成员函数 | 12
 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;
 
 |  
 
- 信号 | 12
 3
 
 | 
 [signal] void QCheckBox::stateChanged(int state);
 
 |  
 
5.2 按钮的使用
下面针对于复选框按钮的三种状态, 为大家展示一下对应的操作流程, 首先第一步搭建一个有树状关系的界面:
 
这些复选框按钮的关系以及 objectName 如下:
 
第二步, 在窗口类的头文件中添加槽函数, 槽函数处理复选框按钮的状态变化:
| 12
 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;
 };
 
 | 
第三步, 在源文件中添加处理逻辑
| 12
 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