目录
刚刚 QWidget 中涉及到的各种 属性/函数/使用方法,针对接下来要介绍的 Qt 的各种控件都是有效的,因为各种控件都是继承自 QWidget 的
接下来本篇博客就学习 Qt 中提供的常用的按钮类控件
QPushButton
使用 QPushButton 表示一个按钮,这也是当前我们最熟悉的一个控件了
我们在前面经常使用pushButton,设置按钮的文本,还使用按钮的点击信号(clicked),并把这个点击信号绑定在槽函数上,于是就会在点击按钮的时候,触发对应的函数调用
QPushButton 继承自 QAbstractButton,这个类是一个抽象类,是其他按钮的父类
抽象类
这个类包含了 纯虚函数,无法创建出实例(对象),就得创建子类,重写上述的纯虚函数,才能够创建出子类的实例
继承关系如下所示:

下面看 QAbstractButton 中,和 QPushButton 相关性较大的属性:
属性 | 说明 |
---|---|
text | 按钮中的文本 |
icon | 按钮中的图标 |
iconSize | 按钮中图标的尺寸 |
shortCut | 按钮对应的快捷键 |
autoRepeat | 按钮是否会重复触发,当鼠标左键按住不放时: 如果设为 true,则会持续产生鼠标点击事件; 如果设为 false,则必须释放鼠标,再次按下鼠标时才能产生点击事件 (相当于游戏手柄上的"连发"效果) |
autoRepeatDelay | 重复触发的延时时间,按住按钮多久之后,开始重复触发 |
autoRepeatInterval | 重复触发的周期 |
添加图标
这里说一句,在我们后续编写代码时,如果用到一些图片等外部资源,都会优先考虑 qrc,除非这个资源太大了
下面创建一个新的qrc文件(前面已经做过类似的操作):
先点新建文件,选择 Qt - Resource,点 Add Prefix 创建前缀,再点 Add Files,此时将图片拷贝到弹出的路径即可,最终结果为下图所示:

接下来通过 图形化 的方式,创建一个按钮:

下面在构造函数中,进行代码的编写:

需要注意:
setIconSize 这个函数中,参数是 QSize,所以需要创建一个 QSize 对象,或是像上图一样创建一个匿名对象,作为参数传入
运行程序:

可以看到我们传入的图片已经被添加为按钮图标了
添加快捷键
前面写过一个例子,通过四个按钮,控制 target 按钮的移动
之前这个移动是通过 鼠标点击按钮 来实现的
此处就可以引入快捷键,通过快捷键来操作,此处按钮直接通过图片来表示
接下来继续创建一个新的qrc文件,在当前路径下创建一个文件夹,再将刚刚图标的 dog.png 和四个箭头图片都放进去:

把图片导入项目的时候,由于图片多了,不想再继续放到项目根目录下了,就创建了 image 目录,把图片放到 image 目录中,此时意味着后续访问这些图片,就需要再路径中带上 image 这一级目录名字
下面编辑 ui 界面,按钮上面没有编辑文本,因为等会会添加图标:

此时 Qt Designer 的右上角如下:
这也就是 Qt 程序运行过程中,对象树的模样,可以更直观的看到对象结构,以及每个对象的 objectName

下面编写构造函数,完成初始化操作:

此时运行程序,效果如下:

实现方向键的槽函数:

此时运行程序后,点击上下左右,target按钮 也会上下左右移动,没有问题
下面设置快捷键,也是需要在 Widget 的构造函数中完成,程序一启动,快捷键就是有效的:
setShortcut函数 的参数是 QKeySequence:

此时就可以按键盘上的 WSAD,控制 target按钮 的上下左右移动啦
这是直接通过按键的名字来设置,虽然简单,但是容易写错
还可以通过按键的枚举来设置快捷键:

上述第二种方式是比较推荐的,因为可以自己选择,如果按键拼写错误会报错
而上面第一种靠自己手输按键,可能会出现按键拼写错误的情况,而且还不报错
上述的设置快捷键只设置了一个键,我们也可以设置组合键:
两种方式是一样的

关于连发功能
键盘快捷键,默认就是能连发的
例如:长按D,就能够一直向右移动
但是鼠标点击按钮则不行,想要鼠标也支持连发,就需要设置 autoReapeat 属性了:

到此 pushButton 添加快捷键的知识就讲述完毕了
QRadioButton
QRadioButton 是单选按钮,可以让我们在多个选项中选择一个
QAbstractButton 中和 QRadioButton 关系较大的属性:
属性 | 说明 |
---|---|
checkable | 是否能选中 |
checked | 是否已经被选中,checkable是checked的前提条件 |
autoExclusive | 是否排他 选中一个按钮之后是否会取消其他按钮的选中 因为是单选按钮,所以对于 QRadioButton 来说默认就是排他的 |
下面以 图形化 的方式创建三个 RadioButton:

再创建一个 Label:

下面分别给这三个按钮,右键点击转到槽:

此时运行程序:

点击男:

点击女:

可以发现 RadioButton 是排他的,并且点击对应的按钮,label 的文本也会发送改变
上述的代码,在刚开始运行程序时,一个选项都没有选,我们也可以在构造函数中添加一个默认的选项:

此时运行程序,会默认选择性别男:

如果想禁用某个选项,比如禁用掉 其他 选择
在构造函数中加入下面的代码:

此时运行程序,点击 其他 按钮,发现没有选中 其他 按钮,但是上面的 label 文本却发生了改变:

所以可以得知 checkable 只是能够让按钮不被选中,但是仍然是可以响应点击事件的
这是不符合预期的,所以我们应该调用 setEnabled 函数完成这个操作:

此时运行程序,发现 其他 按钮变为灰色,无法点击了:

关于toggled
下面说明一下,在前面的操作中,执行转到槽时,大多数使用的 clicked,表示点击
pressed表示按下, released表示抬起
clicked = pressed + released

而关于 clicked(bool) 和 toggled(bool) 一直都没有介绍, 因为在 QPushButton 中,这两个体现不出来效果,而现在在 QRadioButton 中就可以介绍了
下面创建4个 RadioButton:

给 1号QRadioButton 转到槽时,选择 clicked(bool)
给 2号QRadioButton 转到槽时,选择 pressed
给 3号QRadioButton 转到槽时,选择 realeased
给 3号QRadioButton 转到槽时,选择 toggled(bool)

此时运行程序:
多次点击按钮1,会打印多次 clicked

按钮2只要鼠标按下,不用抬起来,也会打印:

按钮3只有按下的鼠标抬起来,才会打印:

点击按钮4,会从false的状态切换到true,所以会打印true:

如果重复点击按钮4,并不会额外打印内容,因为并没有切换状态
下面再点击按钮1,此时按钮4的状态就发送改变了, 所以就会打印 toggled: false:

模拟点餐功能
先创建三个 label,8个 RadioButton:

RadioButton 默认是 排他的,一旦界面上需要存在"多组"单选按钮的时候,我们希望组和组之间不要有影响
例如在选择汉堡、小食、饮料下方,只有同队列的需要排他性,相互之间不希望发送干扰
所以 Qt 中的 QButtonGroup 类,可以针对单选按钮进行分组

此时运行程序,就能够完成我们的需求了:

QCheckBox
上述的 QRadioButton 是单选按钮,这里的 QCheckBox 是复选按钮,可以允许选中多个
和 QChedkBox 最相关的属性,也是 checkable 和 checked,都是继承自 QAbstractButton
下面使用 QCheckBox,完成用户选择完成后,点击下面的 QPushButton 按钮,就能够在 Label 中显示出来:

此时编写 QPushButton 按钮的槽函数:

运行程序,效果如下:

上述功能是点击确认按钮后,上面的 Label 会显示所点击的事情,我们也可以设置 QCheckBox 的槽函数,可以让我们一点击复选框,就显示我们所点击的事情,这里就不多叙述了
按钮类控件到此学习结束