pyQt5 学习笔记(11)QAbstractButton 虚拟按钮控件

一、QAbstracrtButton 简介

前文10小节中,都是相关QWidget控件的特性,它继承自QObject等控件,是所有用户界面对象的基类。同样的QAbstracrtButton 是所有按钮控件的基类,即所有按钮都继承该类,所以学习该类也就学习了所有按钮的通用特性。

二、子类化抽象类:自定义按钮

由于这个类别是虚拟化类别,所以使用该类特性需要借助其子类(它不能被直接实例化)。如以下程序是无法通过编译的:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)
# 错误的使用
btn = QAbstractButton()

if __name__ == '__main__':
    sys.exit(app.exec_())

程勋运行如下所示:
在这里插入图片描述
如果我们想要创建一个QAbstractButton类,需要创建一个继承它的类, 如下所示:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

class Btn(QAbstractButton):
    def paintEvent(self, QPaintEvent):
        pass

btn = Btn()

if __name__ == '__main__':
    sys.exit(app.exec_())

这里还重定义了paintEvent()函数,否则编译不通过并提示需要重载paintEvent()函数。当然,程序运行以后不会有任何显示,如果我们需要自定义按键,则需要在paintEvent()中实现绘图的代码。以下程序示例了一个简单的自定义按钮:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

#1.自定义一个类
class Btn(QAbstractButton):
    #2.重定义绘图事件
    def paintEvent(self, QPaintEvent):
        #3.创建一个绘图对象
        painter = QPainter(self)
        #4.创建一个画笔(rgb颜色,宽度)
        pen = QPen(QColor(111,100,50),3)
        #5.设置画笔
        painter.setPen(pen)
        #6.绘制文本:自定义按键,在位置(20,20)
        painter.drawText(20,20,"自定义按键")
        #7.绘制一个按键边框
        painter.drawEllipse(0,0,60,20)

btn = Btn(w)
w.show()

if __name__ == '__main__':
    sys.exit(app.exec_())

程序运行效果如下所示:
在这里插入图片描述
第14行:重写了paintEvent(),当控件被绘制时,调用该函数
第16行:创建了一个QPainter()对象,QWidget不知继承了QObject也继承QPaintDevice,QWidget及其子类都可以当做一个画纸,被QPainter()绘制
第18行:创建了画笔,QColor()为rgb颜色,参数3为画笔的宽度
第22行:设置了绘制文本位置及其内容
第24行:绘制一个椭圆,参数为(x坐标,y坐标,宽度,高度),它线条的宽度为Qpen决定。

这里只是简单的演示了一个按钮的绘制,它的大小,文本,样式都是无法改变的,实际应用中,我们会通过传参的方法,来让这个类变得更加灵活,由于它是按键的类,所以按键点击事件是可以被捕获的。当然,我们自定义按键也不一定继承该类,可视情况继承其子类。

三、功能(API)

接下来介绍该类一些常用的功能函数,设置文本,图标等。这里为方便不直接使用该类,而是借助pyQt已经实现的子类。

1. 设置文本

按键可以通过setText()来设置按键显示的文本:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

btn = QPushButton(w)
btn.setText('一个按键')


w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

2. 设置图标

按键可以设置一个图标,图标显示在按键的左测,通过setIcon()来设置,还可以通过setIconSize()btn.iconSize()来设置和获取大小,注意图标的大小会影响控件的大小,以下程序示例了一个按键图标的设置:(需要准备一个图标,并清楚其位置,一般放在工程文件中):

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

btn = QPushButton(w)

#1.文本操作
btn.setText('关闭电源')
#2.图标操作
icon = QIcon("powerBtn.ico") #图标的位置,由于本文件通目录,这里只写了名字即可
btn.setIcon(icon)

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

程序运行如下:
在这里插入图片描述

3. 快捷键设置

3.1 快捷设置

可以通过&来设置:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

btn = QPushButton(w)

#1.文本操作
btn.setText('&Power Down')
#2.图标操作
icon = QIcon("powerBtn.ico")
btn.setIcon(icon)

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

程序可以通过按Alt + P来实现和鼠标点击按键一样的效果:
在这里插入图片描述
可以发现,通过按Alt以后,P字母下多了一个横线,这个功能在很多英文界面的软件都有体现,如果你改变了&的位置,也就改变了快捷键。

3.2 函数设置

由于我们按键可能只有一个图标,或者显示文本非英文,如中文等,此时可以通过更灵活的函数setShortcut,其参数为文本格式:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

btn = QPushButton(w)

#1.文本操作
btn.setText('关闭电源')
#2.图标操作
icon = QIcon("powerBtn.ico")
btn.setIcon(icon)
#3. 设置快捷:shift+F1
btn.setShortcut("Shift+F1")

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行程序以后,可以通过shift+F1来按下按键

4. 自动重复

重复指的是当用户点击按钮时不松开,此时按键将不断被发送信号。
一些常用的API:
setAutoRepeat():是否自动重复
setAutoRepeatDelay():按下多久毫秒以后开始自动重复
setAutoRepeatInterval:自动重复的间隔

以下程序演示了自动重复API的使用:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

btn = QPushButton(w)

#1.文本操作
btn.setText('关闭电源')
#2.图标操作
icon = QIcon("powerBtn.ico")
btn.setIcon(icon)
#3.设置快捷:shift+F1
btn.setShortcut("Shift+F1")

#4.自动重复
btn.setAutoRepeat(True)          #自动重复
btn.setAutoRepeatDelay(2000)     #两秒以后开始
btn.setAutoRepeatInterval(500)   #间隔500ms,即1ms重复触发两次

#5. 打印按键点击事件
def press_slot():
    print("按键点击")
    
#6.连接槽函数
btn.pressed.connect(press_slot)

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行:

5. 状态设置

一个按键有多种状态,比如是否有效,是否被点击,是否被选中等等,都可以通过API来设置,也可以通API来获取某一个空间的状态:

函数含义
isDown()是否被按下
setDown(bool)设置按下状态
isChecked()是否被选中
isCheckable()是否能被选中
setChecked(bool)这是被选中
toggle切换选中状态

通常,按键被鼠标点击(但是没有松开)状态称为按下状态,类似单选框或者是复选框,它们还可以被选中,而普通的按键是默认是不能被选中的,但是它可以被设置。以下程序示例了这些接口函数的使:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

#1.创建一个普通按键
btn0 = QPushButton(w)
btn0.move(0,0)
btn0.setText('Push Button')

#2.创建一个单选按键
btn1 = QRadioButton(w)
btn1.move(0,30)
btn1.setText('RadioButton')

#3.创建一个复选复选按键
btn2 = QCheckBox(w)
btn2.move(0,60)
btn2.setText('CheckBox_1')
btn2.setChecked(True)         #设置被选中状态

#3.创建一个复选复选按键
btn3 = QCheckBox(w)
btn3.move(0,90)
btn3.setText('CheckBox_2')
btn3.setEnabled(False)         #失能按键

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行:
在这里插入图片描述
可以看到,程序创建了4个按键,其中2个是复选框,第一个复选框运行默认就别选中,第二个则是无效状态,显然的,复选框被选中的时候,方框内多了一个‘√’,在pyQt中,按钮别选中状态的样式,是可以通过样式表来设置的,以下程序示例将普通按钮的按下状态更改一个背景颜色:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

#1.创建一个普通按键
btn0 = QPushButton(w)
btn0.move(0,0)
btn0.setText('Push Button')
btn0.setStyleSheet("QPushButton:pressed {background-color:green}")

#2.创建一个单选按键
btn1 = QRadioButton(w)
btn1.move(0,30)
btn1.setText('RadioButton')

#3.创建一个复选复选按键
btn2 = QCheckBox(w)
btn2.move(0,60)
btn2.setText('CheckBox_1')
btn2.setChecked(True)         #设置被选中状态

#3.创建一个复选复选按键
btn3 = QCheckBox(w)
btn3.move(0,90)
btn3.setText('CheckBox_2')
btn3.setEnabled(False)         #失能按键

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行以后,当 Push Button 被按下以后,背景颜色将变成绿色。
在这里插入图片描述
这个只示例了一个最简单的修改背景功能,QSS样式表有跟多的功能。

6.排他性

6.1 按键排他性的设置

按钮的排他性指的是按键之间相互排查特性,比如一个性别表格中,会提供男性和女性供用户选择,但是用户只能选择其中一个,典型的应用是单选按钮。以下程序示例了排他性的使用,由于所用QPushButton控件默认无法被选中,所以通过set.Checkable(True)来设置改变它的特性,这样,当我们点击按钮的时候,即便是松开,按钮的按时处于按下状态:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(300,300)

#1.使用for循环创建3个按键
for i in range(0,3):
    btn = QPushButton(w)
    btn.setCheckable(True)        #失能选中状态:是按键能被选中
    btn.setAutoExclusive(True)    #设置排他性
    btn.setText("btn_" + str(i))
    btn.move(0,20*i)

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行:
在这里插入图片描述
注:QPushButton默认没有排他性,而QRadioButton的是默认有排他性的。

6.2 按键排的范围

按键排他性设置为Ture以后,就会和同父控件的其他同样设置为Ture的按键形成互斥状态。所以,我们可以使用不同的父控件,来对按键排他性作一个分类:

from PyQt5.Qt import *
import sys

#创建一个APP
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(210,110)

sub_w1 = QWidget(w)
sub_w1.resize(100,100)

sub_w2 = QWidget(w)
sub_w2.resize(100,100)
sub_w2.move(105,0)

#1.使用for循环创建3个按键
for i in range(0,3):
    btn = QPushButton(sub_w1)
    btn.setCheckable(True)        #失能选中状态:是按键能被选中
    btn.setAutoExclusive(True)    #设置排他性
    btn.setText("btn_" + str(i))
    btn.move(0,20*i)

#1.使用for循环创建3个按键
for i in range(0,3):
    btn = QPushButton(sub_w2)
    btn.setCheckable(True)        #失能选中状态:是按键能被选中
    btn.setAutoExclusive(True)    #设置排他性
    btn.setText("btn_" + str(i))
    btn.move(0,20*i)


w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行:
在这里插入图片描述
可以看到,两侧的按钮互相独立,但是同侧的按钮相互排斥,这就是因为所属父控件不同造成的。

7.设置有效区域

hitButton()可以用来设置控件的有效区域,即使可以设定按钮控件内哪一部被按下,才算是点击了按钮。当控件被按下时候,hitButton()默认返回True,所以,可以通过重写该方法,来实现有效区域的自定义,以下程序示例了,一个按钮只有右半部分被点下时,才算有效点击:

from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("QAbstractButton")
w.resize(210,110)

class Btn(QPushButton):
    def hitButton(self,point):
        print(point)                    #打印point:point为光标点击坐标,相对于控件
        if point.x() > self.width()/2:  #判断x是否在右侧
            return True
        else :
            return False

btn = Btn(w)
btn.setText("点击")

btn.pressed.connect(lambda: print("点击了这个按钮"))

w.show()
if __name__ == '__main__':
    sys.exit(app.exec_())

运行:
在这里插入图片描述
这个控件宽度为75,所以只有当x值大于75/2时,“点击了这个按钮”才会被打印,也就是按键才被认为是按下了。

四、信号

QAbstractButton 类有是个基本的信号:

信号含义
pressed()按键被点击(不松开)
released()按键松开
clicked()按键点击
toggled()按键选择状态翻转(一般用于单选框和复选框)

这里,当鼠标在控件内按下不松开,然后离开控件,判定为:按键松开,但是不算一次点击,即发送released()信号,不发送clicked()信号。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值