【PyQt学习篇 · ⑩】:QAbstractButton的使用
QAbstractButton简介
QAbstractButton 是一个抽象类,无法直接实例化,但它提供了很多在 PyQt 中使用按钮时常用的功能和特性。开发人员可以通过继承 QAbstractButton 类并实现自定义行为来创建自己的按钮类。
子类化抽象类
在 PyQt 中,可以通过子类化 QAbstractButton 的抽象类来创建自定义的按钮类。通过子类化,可以根据需要扩展和重写 QAbstractButton 的功能,并实现自定义的按钮行为。
如以下代码:
btu = QAbstractButton(window)
btu.setText('按钮')
结果:
当我们实例化一个QAbstractButton对象时发生错误,原因就是C++的抽象类无法直接被实例化,而应该去子类化一个类,也就是写一个继承自QAbstractButton的类才可以。
再看以下代码:
class Btu(QAbstractButton):
pass
btu = Btu(window)
btu.setText('按钮')
结果:
当我们想子类化抽象类时,必须要实现抽象类里面的所有抽象方法,即根据以上报错信息,我们必须要实现绘制事件paintEvent
这样一个方法。
示例代码:
from PyQt5.Qt import *
import sys
class Btu(QAbstractButton):
def paintEvent(self, evt):
# 1. 创建一个画家
painter = QPainter(self)
# 2. 创建一支笔 QColor(RGB, 笔的宽度)
pen = QPen(QColor(111, 100, 50), 3)
# 3. 设置笔
painter.setPen(pen)
# 4. 画家画
painter.drawText(25, 50, self.text())
# 画个圆形(长方体的内切圆)
painter.drawEllipse(0, 0, 100, 100)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.resize(300, 300)
btu = Btu(window)
btu.setText('按钮')
btu.move(50, 50)
btu.resize(100, 100)
btu.pressed.connect(lambda: print('按钮被按下'))
window.show()
sys.exit(app.exec_())
运行结果:
图标设置
下面是关于 QAbstractButton 图标设置的一些重要 API 的说明:
-
setIcon(QIcon("resource/h1.png"))
:- 这个方法用于设置按钮的图标。它接受一个 QIcon 参数,表示要在按钮上显示的图标。
-
setIconSize(QSize(w, h))
:- 这个方法用于设置按钮图标的大小。它接受一个 QSize 参数,指定图标的宽度(w)和高度(h)。
-
icon()
:- 这个方法用于获取当前按钮的图标。
-
iconSize()
:- 这个方法用于获取按钮图标的大小。
以上API的使用示例代码:
from PyQt5.Qt import *
from PyQt5.QtGui import QIcon
import sys
class Btu(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.setText('0')
self.resize(50, 50)
# 设置图标
self.setIcon(QIcon('mouse.png'))
# 设置图标大小
self.setIconSize(QSize(50, 50))
# 点击鼠标,数值+1
self.pressed.connect(lambda: self.setText(str(int(self.text()) + 1)))
print(self.icon()) # 获取当前按钮的图标并打印
print(self.iconSize()) # 获取按钮图标的大小并打印
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.resize(300, 300)
window.setWindowTitle('图标设置')
btu = Btu(window)
window.show()
sys.exit(app.exec_())
运行结果:
快捷键设置
可通过指定的快捷键,触发按钮的点击。
- 方式一:有提示文本的。如果提示文本包含
&
符号的,则QAbstractButton会自动创建快捷键。 - 方式二:没有提示文本的。
setShortcut("Alt+G")
方式一的示例代码:
from PyQt5.Qt import *
from PyQt5.QtGui import QIcon
import sys
class Btu(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.setText('a&bc')
self.resize(80, 50)
# 设置图标
self.setIcon(QIcon('mouse.png'))
# 设置图标大小
self.setIconSize(QSize(50, 50))
self.pressed.connect(lambda: print('按钮被按下'))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.resize(300, 300)
window.setWindowTitle('快捷键设置')
btu = Btu(window)
window.show()
sys.exit(app.exec_())
运行结果:
按下“Alt+b”后
方式二示例代码:
修改方式一中Btu
类中的代码:
class Btu(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(80, 50)
self.setShortcut("Alt+a")
# 设置图标
self.setIcon(QIcon('mouse.png'))
# 设置图标大小
self.setIconSize(QSize(50, 50))
self.pressed.connect(lambda: print('按钮被按下'))
运行结果:
按下“Alt+b”后
自动重复
自动重复功能允许按钮在按下并保持按压状态时重复执行其操作。以下是关于 QAbstractButton 自动重复的一些重要 API 的说明:
setAutoRepeat(bool)
:- 这个方法用于设置按钮的自动重复功能是否启用。它接受一个布尔值参数,如果为 True,表示启用自动重复;如果为 False,表示禁用自动重复。
setAutoRepeatInterval(毫秒)
:- 这个方法用于设置按钮自动重复的时间间隔。它接受一个整数参数,表示按下按钮后的重复时间间隔,单位为毫秒。
- 默认情况下,按钮的自动重复时间间隔为 1000 毫秒(即 1 秒)。
setAutoRepeatDelay(毫秒)
:- 这个方法用于设置按钮自动重复的延迟时间。它接受一个整数参数,表示按下按钮后开始重复之前的延迟时间,单位为毫秒。
- 默认情况下,按钮的自动重复延迟时间为 500 毫秒。
autoRepeat()
:- 这个方法用于检查按钮的自动重复功能是否启用。如果按钮启用了自动重复,它将返回 True;否则返回 False。
autoRepeatInterval()
:- 这个方法用于获取按钮的自动重复时间间隔,以毫秒为单位。
autoRepeatDelay()
:- 这个方法用于获取按钮的自动重复延迟时间,以毫秒为单位。
示例代码:
当点击按钮不松时,按钮文本数字连续累增。
from PyQt5.Qt import *
from PyQt5.QtGui import QIcon
import sys
class Btu(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.setText('0')
self.resize(80, 50)
# 设置图标
self.setIcon(QIcon('mouse.png'))
# 设置图标大小
self.setIconSize(QSize(50, 50))
self.pressed.connect(lambda: self.setText(str(int(self.text()) + 1)))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.resize(300, 300)
window.setWindowTitle('自动回复')
btu = Btu(window)
# 设置自动回复
btu.setAutoRepeat(True)
# 设置自动重复的时间间隔
btu.setAutoRepeatInterval(1000) # 1000毫秒
# 设置自动重复的延迟时间
btu.setAutoRepeatDelay(3000) # 3000毫秒
print(btu.autoRepeat())
print(btu.autoRepeatInterval())
print(btu.autoRepeatDelay())
window.show()
sys.exit(app.exec_())
运行结果:
当鼠标一直按下按钮,过了三秒后,每隔一秒就会重复鼠标按下事件,于是数值每隔一秒后自增一。
状态设置
QAbstractButton 是 PyQt5 中的一个按钮类,它提供了一些方法用于设置按钮的状态。以下是关于 QAbstractButton 状态设置的一些重要 API 的说明:
-
isDown()
:- 这个方法用于设置按钮是否处于按下状态(本质上,它是一种“按下”的效果,因为按钮通常是矩形区域,我们不能真的看到按钮被按下)。
- 如果按钮被按下了,则返回 True;否则返回 False。
setDown(bool)
方法用于设置按钮是否处于按下状态,接受一个布尔值参数,如果为 True,表示按钮被按下了,否则表示按钮未被按下。
-
isChecked()
:- 这个方法用于设置按钮是否处于选中状态。
- 如果按钮被选中了,则返回 True;否则返回 False。
setCheckable(bool)
方法用于设置按钮是否可以被选中,接受一个布尔值参数,如果为 True,表示按钮可以被选中;否则表示按钮不可被选中。toggle()
方法用于切换按钮的选中状态,如果按钮原来被选中,则调用toggle()
后会取消选中;如果原来没被选中,则toggle()
后会将其设置为被选中状态。
-
isEnabled()
和setEnabled(bool)
:isEnabled()
方法用于检查按钮是否处于可用状态。如果按钮可用,则返回 True;否则返回 False。setEnabled(bool)
方法用于设置按钮的可用状态。如果将参数设置为 True,表示按钮可用,否则表示按钮不可用。
示例1代码:
from PyQt5.Qt import *
from PyQt5.QtGui import QIcon
import sys
class Btu(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(50, 50)
self.setIcon(QIcon('mouse.png'))
self.setIconSize(QSize(50, 50))
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('状态设置')
window.resize(300, 300)
btu = Btu(window)
# 创建三个按钮
push_btu = QPushButton(window)
push_btu.setText('这是一个按钮')
push_btu.move(100, 50)
radio_btu = QRadioButton(window)
radio_btu.setText('这是一个radio')
radio_btu.move(100, 100)
checkbox_btu = QCheckBox(window)
checkbox_btu.setText('这是一个checkbox')
checkbox_btu.move(100, 150)
# 把三个按钮,置为按下状态
push_btu.setDown(True)
radio_btu.setDown(True)
checkbox_btu.setDown(True)
print('是否被按下:')
print(push_btu.isDown())
print(radio_btu.isDown())
print(checkbox_btu.isDown())
print('是否处于选中状态:')
print(push_btu.isChecked())
print(radio_btu.isChecked())
print(checkbox_btu.isChecked())
print('是否可以被选中:')
print(push_btu.isCheckable())
print(radio_btu.isCheckable())
print(checkbox_btu.isCheckable())
window.show()
sys.exit(app.exec_())
运行结果:
示例2代码:
from PyQt5.Qt import *
from PyQt5.QtGui import QIcon
import sys
class Btu(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.resize(50, 50)
self.setIcon(QIcon('mouse.png'))
self.setIconSize(QSize(50, 50))
def change_type():
push_btu.toggle()
radio_btu.toggle()
checkbox_btu.toggle()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('状态设置')
window.resize(300, 300)
btu = Btu(window)
btu.pressed.connect(change_type)
# 创建三个按钮
push_btu = QPushButton(window)
push_btu.setText('这是一个按钮')
push_btu.move(100, 50)
push_btu.setCheckable(True) # 设置为可以被选中
radio_btu = QRadioButton(window)
radio_btu.setText('这是一个radio')
radio_btu.move(100, 100)
checkbox_btu = QCheckBox(window)
checkbox_btu.setText('这是一个checkbox')
checkbox_btu.move(100, 150)
window.show()
sys.exit(app.exec_())
运行结果:
示例3代码:
在示例2代码的基础上,设置三个按钮为不可用状态,观察其是否还可以切换状态。
push_btu.setEnabled(False)
radio_btu.setEnabled(False)
checkbox_btu.setEnabled(False)
运行结果:
还是可以切换状态
排他性
以下是有关排他性的重要 API 的说明:
autoExclusive()
和setAutoExclusive(bool)
:autoExclusive()
方法用于检查按钮是否启用了排他性。如果按钮启用了排他性,则返回 True;否则返回 False。setAutoExclusive(bool)
方法用于设置按钮是否启用排他性。如果参数设置为 True,表示启用按钮的排他性,即同一组中的按钮只能有一个处于选中状态;否则表示不启用排他性,即同一组中的按钮可以同时选中多个。
示例1代码:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('排他性')
window.resize(300, 300)
for i in range(3):
btu = QPushButton(window)
btu.setText('btu' + str(i))
btu.move(50*i, 50*i)
print(btu.autoExclusive()) # 打印三个按钮的排他性
btu.setCheckable(True) # 设置三个按钮为可选中
window.show()
sys.exit(app.exec_())
运行结果:
因为三个按钮排他性都为False,所以都可以被选中
示例2代码:
btu.setAutoExclusive(True) # 设置排他性为True
运行结果:
设置三个按钮的排他性为True后,只能选择其中一个按钮。
点击
在 PyQt5 中,QAbstractButton 类提供了两个方法来处理按钮的点击事件。以下是有关点击事件的两个重要 API 的说明:
click()
:click()
方法用于手动触发按钮的点击事件。当程序调用该方法时,按钮将执行与点击事件相关的操作,就好像用户实际点击了按钮一样。
animateClick(ms)
:animateClick(ms)
方法用于模拟按钮的动画点击效果,即在一段时间内模拟按钮的按下和释放动作。该方法会触发按钮的点击事件,并在一定时间内呈现按钮按下和释放的效果。- 参数
ms
表示动画点击的持续时间(以毫秒为单位)。在这段时间内,按钮会呈现按下状态,然后逐渐恢复到正常状态。
示例代码:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
window = QWidget()
window.resize(300, 300)
window.setWindowTitle('点击')
btu = QPushButton(window)
btu.setText('按钮')
btu.move(100, 100)
def text():
print('点击了这个按钮')
btu.pressed.connect(text)
btu.click() # 模拟鼠标点击
window.show()
sys.exit(app.exec_())
运行结果:
窗口出现后,模拟点击,进入槽函数,打印结果。
将以上代码中的 btu.click()
换成 btu.animateClick(2000)
后运行,在窗口出现后按钮被模拟点击2s,相当于按下按钮2s后再松开,展现一个按钮被点击的动画。
运行结果:
设置点击有效区域
在 PyQt5 中,QAbstractButton 类提供了一个重写函数 hitButton(QPoint)
,用于实现按钮的模拟点击。以下是 hitButton(QPoint)
的说明:
hitButton(QPoint)
函数:hitButton(QPoint)
函数用于处理按钮的模拟点击事件。当用户在图形界面上模拟点击按钮时,该函数将被调用,并传入点击的坐标。- 点击有效返回
True
,否则返回False
- 参数 QPoint 表示点击的坐标,是一个包含 x 和 y 坐标值的 QPoint 对象,其中以按钮的左上角为坐标原点。
示例1代码:
from PyQt5.Qt import *
import sys
class Btu(QPushButton):
def hitButton(self, point):
print(point)
return False
if __name__ == '__main__':
app = QApplication(sys.argv)
window = QWidget()
window.resize(300, 300)
window.setWindowTitle('设置有效区域')
btu = Btu(window)
btu.setText('点击')
btu.move(100, 100)
btu.pressed.connect(lambda: print('按钮被点击了'))
window.show()
sys.exit(app.exec_())
运行结果:
点击按钮后槽函数并没有被执行,因为在hitButton(self, point)
函数中返回了False
,判定为本次点击无效。
示例2代码:
设置点击按钮左半部分无效,点击右半部分有效。
class Btu(QPushButton):
def hitButton(self, point):
print(point)
if point.x() > self.width() / 2:
return True
return False
运行结果:
可用信号
在 PyQt5 中,QAbstractButton 类提供了多个可用信号,用于处理按钮被按下、释放、单击和切换等事件。以下是有关信号的四个重要 API 的说明:
pressed()
:pressed()
信号在按钮被按下时发出。对于鼠标事件,指鼠标按下左键并保持键盘状态的情况。
released()
:released()
信号在按钮被释放时发出。对于鼠标事件,指放开左键。
clicked(checked=false)
:clicked(checked=false)
信号在按钮被单击时发出。如果按钮是可切换的,则 checked 参数表示按钮状态是否已切换。- 对于弹起事件,也会发出 clicked 信号。这意味着 clicked 信号发出时,不一定意味着按钮处于按下状态。
toggled(bool checked)
:toggled(bool checked)
信号在按钮的状态切换时发出。如果按钮未切换,则 checked 为 False;如果按钮已切换,则 checked 为 True。- 这个信号只对可切换的按钮有效。
示例1代码:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('可用信号')
window.resize(300, 300)
btu = QPushButton(window)
btu.move(100, 100)
btu.setText('点击')
btu.pressed.connect(lambda: print('按钮被按下了'))
btu.released.connect(lambda: print('按钮被释放了'))
window.show()
sys.exit(app.exec_())
运行结果:
示例2代码:
from PyQt5.Qt import *
import sys
app = QApplication(sys.argv)
window = QWidget()
window.setWindowTitle('可用信号')
window.resize(300, 300)
btu = QPushButton(window)
btu.move(100, 100)
btu.setText('点击')
btu.toggled.connect(lambda value: print('按钮选中状态发生了改变', value))
window.show()
sys.exit(app.exec_())
运行结果:
点击按钮后没有任何打印结果
在示例2中加入以下代码:
设置按钮为可选状态
btu.setCheckable(True)
运行结果: