QAbstractButton功能作用
- 提示文本
- 图标相关
- 设置快捷键
- 自动重复
- 状态设置
- 排他性(独占性)
- 模拟点击
- 设置有效区域
- 可用信号
- 提示文本
setText(str) # 设置按钮提示文本 text() # 获取按钮提示文本
- 图标相关
# 图标展示在提示文本的左侧 setIcon(QIcon("resource/h1.png")) # 设置图标 setIconSize(QSize(w, h)) # 设置图标大小 icon() # 获取图标 iconSize() # 获取图标大小
- 设置快捷键
# 方法1:有提示文本 # 如果提示文本包含&符号('&')的, 则QAbstractButton会自动创建快捷键 # btn.setText('a&bc') ————> 快捷键为:Alt + b # 方法2:没有提示文本 setShortcut("Alt+G") # 设置控件快捷键
- 自动重复
- 当按下按钮不松的时候,不断发射信号
setAutoRepeat(bool) # 设置自动重复 setAutoRepeatInterval(毫秒) # 设置自动重复检测间隔 setAutoRepeatDelay(毫秒) # 设置初次检测延迟 autoRepeat() # 获取是否自动重复 autoRepeatInterval() # 获取自动重复检测间隔 autoRepeatDelay() # 获取初次检测延迟
- 状态设置
setDown(bool) # 设置按钮, 是否被按下 isDown() # 获取按钮是否被按下 setCheckable(bool) # 设置按钮是否可以被选中 isCheckable() # 获取按钮是否可以被选中 setChecked(bool) # 设置按钮是否被选中 isChecked() # 获取按钮是否被选中 toggle() # 切换选中与非选中状态 # 继承自QWidget中的是否可用状态 setEnabled(bool) # 设置按钮是否可用(灰色) isEnabled() # 获取按钮是否可用
- 排他性
- 概念:如果同时存在多个按钮,而此时所有按钮又设置了排他性,则在同一时刻只能选中一个按钮
- 排他性是相对于同级控件而言。也就是具有相同父控件的控件具有排他性,不同父控件之间的子控件互不影响
- 后面会讲QButtonGroup(抽象按钮组)用于解决这个问题,比设置不同父控件更方便
setAutoExclusive(bool) # 设置自动排他 autoExclusive() # 获取是否自动排他(一般按钮都是False, 只有单选按钮是True)
- 模拟点击
click() # 普通点击 animateClick(ms) # 动画点击,点击后延迟到指定时间后释放
- 设置有效区域
重写父类 hitButton(QPoint) 方法 # 返回True则点击有效,会触发点击(按下pressed和释放released)事件 # 返回False则点击无效,不会触发点击(按下pressed和释放released)事件 # 需要重写方法,所以要自定义继承类 class Btn(QPushButton): def hitButton(self, pos) -> bool: # pos:接收鼠标在按钮上点击的坐标(x, y) print(pos) # 返回True则有效,会触发点击(按下和释放)事件 # return True # 返回False则无效,不会触发点击(按下和释放)事件 return False btn = Btn(window) btn.setText('按钮') btn.pressed.connect(lambda : print('按钮被点击了')) # 由于可以接收到鼠标点击的坐标,那么就可以对坐标进行判断,根据判断结果来返回True和False class Btn(QPushButton): def hitButton(self, pos) -> bool: # pos:接收鼠标在按钮上点击的坐标(x, y) # print(pos) # 返回True则有效,会触发点击事件 # return True # 返回False则无效,不会触发点击事件 # return False # 判断鼠标点击的x坐标释放大于按钮宽度的一半 if pos.x() > self.width() / 2: # 如果大于,则返回True,有效 return True return False btn = Btn(window) btn.setText('按钮') btn.pressed.connect(lambda : print('按钮被点击了')) btn.released.connect(lambda : print('按钮被释放了'))
- 可用信号
pressed() # 鼠标按下信号 released() # 鼠标释放信号(控件内松开鼠标/鼠标移出控件范围后) clicked(checked = False) # 单击信号(控件内按下+控件内释放),传递按钮是否被选中状态 toffled(bool checked) # 选中状态切换信号(一般在单选框或者复选框中使用),传递按钮是否被选中状态
- 案例
- 案例1
from PyQt5.Qt import * import sys app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('按钮功能介绍-抽象类') # ****************提示文本****************** 开始 # btn = QPushButton(window) # btn.setText('1') # btn.move(50, 30) # # def btn_cao(): # num = int(btn.text()) + 1 # btn.setText(str(num)) # # # btn.pressed.connect(btn_cao) # btn.clicked.connect(btn_cao) # ****************提示文本****************** 结束 # ****************图标相关****************** 开始 # # 声明QIcon对象 # ico = QIcon('../ico/logo.ico') # # 给按钮设置图标 # btn.setIcon(ico) # # # 声明QSize对象 # size = QSize(50, 50) # # 设置图标大小 # btn.setIconSize(size) # ****************图标相关****************** 结束 # ****************设置快捷键****************** 开始 # 方法一: 有提示文本的 # btn.setText('a&bc') # 方法二:没有提示文本 # btn.setShortcut('s') # btn.setShortcut('alt+s') # btn.setShortcut('ctrl+s') # btn.setShortcut('ctrl+shift+s') # btn.pressed.connect(lambda :print('按钮被按下了')) # ****************设置快捷键****************** 结束 # ****************自动重复****************** 开始 # btn.setText('1') # # 设置自动重复 # btn.setAutoRepeat(True) # # 设置初次监测自动重复延迟 # btn.setAutoRepeatDelay(2000) # # 设置自动重复监测间隔时间 # btn.setAutoRepeatInterval(2000) # # btn.pressed.connect(lambda :btn.setText(str(int(btn.text())+1))) # ****************自动重复****************** 结束 # ****************状态设置****************** 开始 # 添加三种按钮 # push_button = QPushButton(window) # push_button.setText('这是QPushButton') # push_button.move(100, 100) # # radio_button = QRadioButton(window) # radio_button.setText('这是QRadioButton') # radio_button.move(100, 150) # # checkbox = QCheckBox(window) # checkbox.setText('这是QCheckBox') # checkbox.move(100, 200) # # # 设置push_button按钮被按下时候的样式:背景色为红色 # push_button.setStyleSheet("QPushButton:pressed {background-color: red;}") # 设置三种按钮均为按下状态 # push_button.setDown(True) # radio_button.setDown(True) # checkbox.setDown(True) # 获取三个按钮是否被按下状态 # print(push_button.isDown()) # print(radio_button.isDown()) # print(checkbox.isDown()) # # 获取三个按钮是否可用被选中 # print(push_button.isCheckable()) # -> False # print(radio_button.isCheckable()) # -> True # print(checkbox.isCheckable()) # -> True # push_button默认是不可被选中状态 # # 设置push_button可以被选中 # push_button.setCheckable(True) # # print(push_button.isCheckable()) # # # 设置三个按钮均被选中 # push_button.setChecked(True) # radio_button.setChecked(True) # checkbox.setChecked(True) # # # # 获取三个按钮是否被选中 # # print(push_button.isChecked()) # # print(radio_button.isChecked()) # # print(checkbox.isChecked()) # # btn = QPushButton(window) # btn.setText('反选') # btn.move(100, 250) # # def cao(): # push_button.toggle() # radio_button.toggle() # checkbox.toggle() # # # radio_button.setChecked(not radio_button.isChecked()) # # btn.pressed.connect(cao) # # # 设置按钮不可用(灰色),通过代码设置可以改变状态 # push_button.setEnabled(False) # radio_button.setEnabled(False) # checkbox.setEnabled(False) # ****************状态设置****************** 结束 # ****************排他性设置****************** 开始 # for i in range(1, 4): # btn = QPushButton(window) # btn.setText('btn' + str(i)) # btn.move(50, i * 50) # # 设置btn按钮可以被选中 # btn.setCheckable(True) # # 设置btn按钮开启排他性 # btn.setAutoExclusive(True) # # for i in range(1, 4): # rad = QRadioButton(window) # rad.setText('rad' + str(i)) # rad.move(200, i * 50) # # QRadioButton类型的按钮默认开启排他性 # # 关闭rad按钮的排他性 # rad.setAutoExclusive(False) # # for i in range(1, 4): # chb = QCheckBox(window) # chb.setText('chb' + str(i)) # chb.move(300, i * 50) # # 设置chb按钮开启排他性 # chb.setAutoExclusive(True) # # # w = QWidget(window) # w.move(0, 220) # # for i in range(0, 3): # btn = QPushButton(w) # btn.setText('btn' + str(i)) # btn.move(50, i * 50) # # 设置btn按钮可以被选中 # btn.setCheckable(True) # # 设置btn按钮开启排他性 # btn.setAutoExclusive(True) # # for i in range(0, 3): # rad = QRadioButton(w) # rad.setText('rad' + str(i)) # rad.move(200, i * 50) # # for i in range(0, 3): # chb = QCheckBox(w) # chb.setText('chb' + str(i)) # chb.move(300, i * 50) # ****************排他性设置****************** 结束 # ****************模拟点击****************** 开始 # btn1 = QPushButton(window) # btn1.setText('按钮1') # btn1.move(100, 100) # btn1.pressed.connect(lambda :print('按钮1被按下了')) # # btn2 = QPushButton(window) # btn2.setText('按钮2') # btn2.move(200, 100) # btn2.pressed.connect(lambda :print('按钮2被按下了')) # # btn3 = QPushButton(window) # btn3.setText('模拟点击') # btn3.move(150, 150) # # def test(): # btn1.click() # btn2.animateClick(2000) # # btn3.pressed.connect(test) # ****************模拟点击****************** 结束 # ****************设置有效区域****************** 开始 # class Btn(QPushButton): # def hitButton(self, pos) -> bool: # # pos:接收鼠标在按钮上点击的坐标(x, y) # # print(pos) # # 返回True则有效,会触发点击事件 # # return True # # 返回False则无效,不会触发点击事件 # # return False # # # 判断鼠标点击的x坐标释放大于按钮宽度的一半 # if pos.x() > self.width() / 2: # # 如果大于,则返回True,有效 # return True # return False # # btn = Btn(window) # btn.setText('按钮') # btn.pressed.connect(lambda : print('按钮被点击了')) # btn.released.connect(lambda : print('按钮被释放了')) # ****************设置有效区域****************** 结束 window.show() sys.exit(app.exec_())
- 案例2:设置按钮有效区域为圆形
- 设置有效区域为圆形,实际就是判断鼠标点击的点到圆心的距离是否小于半径
-
from PyQt5.Qt import * import sys app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('按钮功能介绍-抽象类') # ****************设置有效区域为圆形****************** 开始 # 设置有效区域为圆形,实际就是判断鼠标点击的点到圆心的距离是否小于半径 # 计算两点之间的距离,就需要通过勾股定律进行计算 class Btn(QPushButton): def hitButton(self, pos) -> bool: # 1. 获取圆心(中心点)的坐标 centre_x = self.width()/2 centre_y = self.height()/2 # 2. 获取鼠标点击点的坐标 targ_x = pos.x() targ_y = pos.y() # 3. 鼠标点击点到圆心的横向距离 dist_h = abs(targ_x - centre_x) # 4. 鼠标点击点到圆心的纵向距离 dist_l = abs(targ_y - centre_y) # 5. 计算鼠标点击点到圆心的距离:(横向距离的平方 + 纵向距离的平方)再求平方根 dist = (dist_h ** 2 + dist_l ** 2) ** 0.5 # 用鼠标点击点到圆心的距离与半径进行比较 if dist < self.width() / 2: return True return False btn = Btn(window) btn.resize(200, 200) btn.move(150, 150) btn.setText('按钮') btn.pressed.connect(lambda : print('按钮被点击了')) btn.released.connect(lambda : print('按钮被释放了')) # ****************设置有效区域为圆形****************** 结束 window.show() sys.exit(app.exec_())
- 如果我们需要在按钮中绘制一个圆形边框,那么我们需要重写按钮的绘制事件
from PyQt5.Qt import * import sys app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('按钮功能介绍-抽象类') # ****************设置有效区域为圆形****************** 开始 # 设置有效区域为圆形,实际就是判断鼠标点击的点到圆心的距离是否小于半径 # 计算两点之间的距离,就需要通过勾股定律进行计算 class Btn(QPushButton): def hitButton(self, pos) -> bool: # 1. 获取圆心(中心点)的坐标 centre_x = self.width()/2 centre_y = self.height()/2 # 2. 获取鼠标点击点的坐标 targ_x = pos.x() targ_y = pos.y() # 3. 鼠标点击点到圆心的横向距离 dist_h = abs(targ_x - centre_x) # 4. 鼠标点击点到圆心的纵向距离 dist_l = abs(targ_y - centre_y) # 5. 计算鼠标点击点到圆心的距离:(横向距离的平方 + 纵向距离的平方)再求平方根 dist = (dist_h ** 2 + dist_l ** 2) ** 0.5 # 用鼠标点击点到圆心的距离与半径进行比较 if dist < self.width() / 2: return True return False def paintEvent(self, a0) -> None: # 按钮的绘制事件 # 1. 声明一个画家(指明画板) painter = QPainter(self) # 2. 创建画笔(RGB颜色,粗细) pen = QPen(QColor(200,30,50), 3) # 3. 给画家设置画笔 painter.setPen(pen) # 4. 画家开始绘制:椭圆 painter.drawEllipse(0, 0, 200, 200) pass btn = Btn(window) btn.resize(200, 200) btn.move(150, 150) btn.setText('按钮') btn.pressed.connect(lambda : print('按钮被点击了')) btn.released.connect(lambda : print('按钮被释放了')) # ****************设置有效区域为圆形****************** 结束 window.show() sys.exit(app.exec_())
- 运行结果可以看到,按钮仅仅只有一个圈了,之前设置的提示文本和按钮边框都没有了
- 原因:我们重写了按钮绘制事件,只绘制了一个椭圆,所以其他的内容都没有被绘制出来
- 解决:在重写的绘制事件中,调用父类的绘制事件 super().paintEvent(a0)
from PyQt5.Qt import * import sys import time app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('按钮功能介绍-抽象类') # ****************设置有效区域为圆形****************** 开始 # 设置有效区域为圆形,实际就是判断鼠标点击的点到圆心的距离是否小于半径 # 计算两点之间的距离,就需要通过勾股定律进行计算 class Btn(QPushButton): def hitButton(self, pos) -> bool: # 1. 获取圆心(中心点)的坐标 centre_x = self.width()/2 centre_y = self.height()/2 # 2. 获取鼠标点击点的坐标 targ_x = pos.x() targ_y = pos.y() # 3. 鼠标点击点到圆心的横向距离 dist_h = abs(targ_x - centre_x) # 4. 鼠标点击点到圆心的纵向距离 dist_l = abs(targ_y - centre_y) # 5. 计算鼠标点击点到圆心的距离:(横向距离的平方 + 纵向距离的平方)再求平方根 dist = (dist_h ** 2 + dist_l ** 2) ** 0.5 # 用鼠标点击点到圆心的距离与半径进行比较 if dist < self.width() / 2: return True return False def paintEvent(self, a0) -> None: super(Btn, self).paintEvent(a0) # 按钮的绘制事件 # 1. 声明一个画家(指明画板) painter = QPainter(self) # 2. 创建画笔(RGB颜色,粗细) pen = QPen(QColor(200,30,50), 3) # 3. 给画家设置画笔 painter.setPen(pen) # 4. 画家开始绘制:椭圆 painter.drawEllipse(0, 0, 200, 200) pass btn = Btn(window) btn.resize(200, 200) btn.move(150, 150) btn.setText('按钮') btn.pressed.connect(lambda : print('按钮被点击了',time.time())) btn.released.connect(lambda : print('按钮被释放了')) # ****************设置有效区域为圆形****************** 结束 window.show() sys.exit(app.exec_())
- 案例3:按钮可用信号
from PyQt5.Qt import * import sys app = QApplication(sys.argv) window = QWidget() window.resize(500, 500) window.setWindowTitle('按钮功能介绍-可用信号') btn = QPushButton(window) btn.setText('可用信号') btn.move(150, 100) # 设置btn按钮可以被选中 btn.setCheckable(True) def clicked_cao(checked): # checked接收的是clicked信号传过来的按钮是否被选中状态 print('按钮被点击了', checked) def toggled_cao(checked): # checked接收的是clicked信号传过来的按钮是否被选中状态 print('按钮选择状态发生了变化',checked) # 按钮按下信号 btn.pressed.connect(lambda : print('按钮被按下了')) # 按钮释放信号 btn.released.connect(lambda : print('按钮被释放了')) # 按钮点击信号,传递按钮是否被选中状态True/False # btn.clicked.connect(lambda value : print('按钮被释放了', value)) btn.clicked.connect(clicked_cao) # 按钮选择状态切换信号,传递按钮是否被选中状态True/False # btn.toggled.connect(lambda value: print('按钮选择状态发生了变化', value)) btn.toggled.connect(toggled_cao) window.show() sys.exit(app.exec_())