Python桌面开发pyqt5—QAbstractButton及子类

Qt控件:QPushButton、QRadioButton等的基本操作与特性
本文详细介绍了Qt库中的QPushButton、QRadioButton、QToolButton和QCommandLinkButton等控件的构造方式、文本与图标设置、快捷键、点击事件、菜单绑定、右键菜单、绘图事件以及互斥性和信号处理等内容。

QPushButton

构造方式

  1. QPushButton(self):只指定附加在哪个容器上
  2. QPushButton('按钮', self):同时指定文本
  3. QPushButton(QIcon('./resources/flower.png'), '按钮', self):同时指定图标

设置文本与图标

btn = QPushButton(self)

# 设置文本
btn.setText('按钮')

# 设置图标
btn.setIcon(QIcon(path))		
# 设置图标大小
btn.setIconSize(QSize(w, h))

# 设置为扁平
btn.setFlat(True)
# 获取是否为扁平
print(btn.isFlat())
# 设置为扁平之后,按钮的背景颜色不能再改变,但貌似字体颜色可以改
btn.setStyleSheet('background-color:red;')

# 设置为鼠标点击后默认选择
btn.setAutoDefault(True)
# 获取是否为鼠标点击后默认选择
print(btn.autoDefault())
# 设置为一开始就为默认选择状态
btn.setDefault(True)

快捷键

btn = QPushButton('按钮', self)
# 法1: &绑定ALT+第一个字母a,注意一个按钮只能有一个&
btn.setText('&a')
# 法2: 这种方式更好
btn.setShortcut('Alt+a')

触发点击

btn = QPushButton('按钮', self)
# 瞬间点击
btn.click()
# 点击,并设置点击持续时间(ms)
btn.animateClick(2000)  # 模拟按下了2s

按住自动触发点击事件

btn = QPushButton('1', self)

# 设置是否自动重复
btn.setAutoRepeat(True)
# 初次检测的开始时间(ms)
btn.setAutoRepeatDelay(1000)
# 设置检测的间隔(ms)
btn.setAutoRepeatInterval(1000)

# 获取自动重复的信息
print(btn.autoRepeat(), btn.autoRepeatDelay(), btn.autoRepeatInterval())

btn.clicked.connect(lambda : print('按钮被点击了...'))

菜单绑定到按钮

btn = QPushButton('按钮', self)

# 实例化菜单
menu = QMenu()

# 实例化行为
# QAction也可以直接使用构造函数在实例化对象时设置属性
new_action = QAction(QIcon('./resources/pink_flower.png'), '新建', menu)
open_action = QAction(QIcon('./resources/blue_flower.png'), '打开', menu)
quit_action = QAction(QIcon('./resources/red_flower.png'), '退出', menu)

# 行为绑定函数
new_action.triggered.connect(lambda: print('新建文件'))
open_action.triggered.connect(lambda: print('打开文件'))
quit_action.triggered.connect(lambda: print('退出程序'))

# 设置子菜单
child_menu = QMenu(menu)
child_menu.setTitle('子菜单')  # 设置子菜单标题
child_action = QAction('子行为', child_menu)  # 给子菜单设置子行为
child_menu.addAction(child_action)  # 将子行为添加到子菜单

# 将行为添加到菜单
menu.addAction(new_action)
menu.addAction(open_action)
menu.addMenu(child_menu)  # 添加子菜单
menu.addSeparator()  # 添加分割线
menu.addAction(quit_action)

# 将菜单添加到按钮
btn.setMenu(menu)

# 获取菜单
print(btn.menu())

# 显示菜单
# btn.showMenu()	#注,应该放在root.show()窗口展示之后

在这里插入图片描述

右击菜单

def contextMenuEvent(self, event):
    '''要设置右键菜单只需重写这个类方法'''
    menu = QMenu(self)
    # 实例化行为
    new_action = QAction('新建', menu)
    open_action = QAction('打开', menu)
    quit_action = QAction('退出', menu)
    # 行为绑定函数
    new_action.triggered.connect(lambda: print('新建文件'))
    open_action.triggered.connect(lambda: print('打开文件'))
    quit_action.triggered.connect(lambda: print('退出程序'))
    # 设置子菜单
    child_menu = QMenu(menu)
    child_menu.setTitle('子菜单')
    child_action = QAction('子行为', child_menu)
    child_menu.addAction(child_action)
    # 将行为添加到菜单
    menu.addAction(new_action)
    menu.addAction(open_action)
    menu.addMenu(child_menu)
    menu.addSeparator()
    menu.addAction(quit_action)

    # 在某一点显示菜单
    menu.exec_(event.globalPos())  # 方法globalPos()获取全局坐标,因为设置右击菜单的坐标只能是绝对坐标

在这里插入图片描述

paintEvent案例

设置有效区域为一个内切圆并把区域绘制出来

class Btn(QPushButton):
    def hitButton(self, point):  # 返回的点是相对按钮左上角的位置而不是绝对位置
        # 只有点击按钮内切圆才会生效
        r = self.width() / 2
        rp_x = self.width() / 2
        rp_y = self.height() / 2
        distance = math.sqrt((point.x() - rp_x) ** 2 + (point.y() - rp_y) ** 2)
        print(distance)
        if distance <= r:
            return True
        else:
            return False

    def paintEvent(self, event):
        super().paintEvent(event)
        painter = QPainter(self)
        painter.setPen(QPen(QColor(0, 0, 200), 1))  # 3代表线条宽度
        painter.drawEllipse(self.rect())  # 在自己的矩形框画椭圆


btn = Btn(self)
btn.setText('按钮')
btn.resize(200, 200)
btn.move(100, 50)
btn.pressed.connect(lambda: print('按下了'))

在这里插入图片描述

信号

btn = QPushButton(self)
btn.setText('按钮')
# 可触发toggle事件
btn.setCheckable(True)
# 按下事件
btn.pressed.connect(lambda: print('按下了'))
# 释放事件
btn.released.connect(lambda: print('松开了'))
# 点击事件(
btn.clicked.connect(lambda val: print('点击了,选中状态是{}'.format(val)))
# 状态切换事件
btn.toggled.connect(lambda val: print('状态改变了,选中状态为{}'.format(val)))

QRadioButton

设置文本与图标

rb_m = QRadioButton('男', self)  # 注意:当只设置一个按钮,可以再次点击取消选中;但若有多个按钮,不能取消选中,即最少有一个被选中的
rb_m.move(50, 50)
rb_f = QRadioButton('女', self)
rb_f.move(50, 100)

# 设置图标
rb_f.setIcon(QIcon('./resources/pink_flower.png'))
rb_m.setIcon(QIcon('./resources/blue_flower.png'))

快捷键

rb_m = QRadioButton('男', self)  # 注意:当只设置一个按钮,可以再次点击取消选中;但若有多个按钮,不能取消选中,即最少有一个被选中的
rb_m.move(50, 50)
rb_f = QRadioButton('女', self)
rb_f.move(50, 100)

rb_m.setShortcut('Alt+m')
rb_f.setShortcut('Alt+f')

checked与enabled状态

push_btn = QPushButton(self)
push_btn.move(50, 50)
push_btn.setText('QpushButton')
radio_btn = QRadioButton(self)
radio_btn.move(100, 100)
radio_btn.setText('QRadioButton')
check_box = QCheckBox(self)
check_box.move(150, 150)
check_box.setText('QCheckBox')

# 设置按下状态 pressed qss
push_btn.setStyleSheet('QPushButton:pressed {background-color:red;}')
push_btn.setDown(False)
radio_btn.setDown(False)
check_box.setDown(False)

# 查看是否可以被选中(是否有这种能力)
push_btn.setCheckable(True)  # 要使push_button能被选中必须写这个
# 查看按钮是否被选中()当前的状态
print(push_btn.isChecked(), radio_btn.isChecked(), check_box.isChecked())

# 控制其他按钮的checked状态
def press_func_state():
    '''控制其他按钮的状态'''
    # 两种方式
    push_btn.setChecked(not push_btn.isChecked())	# 设置选中
    radio_btn.toggle()
    check_box.toggle()
btn = QPushButton(self)
btn.setText('切换其他按钮checked')
btn.pressed.connect(press_func_state)

# 控制其他按钮的enabled状态
def press_func_state():
    '''控制其他按钮的状态'''
    # 两种方式
    push_btn.setEnabled(not push_btn.isEnabled())
    radio_btn.setEnabled(not radio_btn.isEnabled())
    check_box.setEnabled(not check_box.isEnabled())
btn2 = QPushButton(self)
btn2.move(200, 0)
btn2.setText('切换其他按钮enabled')
btn2.pressed.connect(press_func_state)
# 获取能否交互
# 注意,即使不能交互,也可以通过代码控制选中状态isChecked
print(push_btn.isEnabled(), radio_btn.isEnabled(), check_box.isEnabled())

widget多组互斥

# 多组互斥: 设置多个Widget控件,他们之间互不干扰
red = QWidget(self)
red.move(0, 0)
red.resize(150, 150)
red.setStyleSheet('background-color:red;')

pink = QWidget(self)
pink.move(red.x() + red.width(), red.y())
pink.resize(150, 150)
pink.setStyleSheet('background-color:pink;')

rb_m = QRadioButton('男', red)
rb_m.move(red.x(), red.y())
rb_f = QRadioButton('女', red)
rb_f.move(red.x(), red.y() + 50)

rb_y = QRadioButton('是', pink)
rb_y.move(0, 0)
rb_n = QRadioButton('否', pink)
rb_n.move(0, 50)

在这里插入图片描述

QButtonGroup多组互斥

rb_m = QRadioButton('男', self)
rb_m.move(100, 50)
rb_f = QRadioButton('女', self)
rb_f.move(100, 100)
rb_f.setChecked(True)
rb_y = QRadioButton('是', self)
rb_y.move(200, 50)
rb_n = QRadioButton('否', self)
rb_n.move(200, 100)

# 把按钮分配到两组
sex_group = QButtonGroup(self)
sex_group.addButton(rb_m)
sex_group.addButton(rb_f)
yn_group = QButtonGroup(self)
yn_group.addButton(rb_n, 0)  # 可以设置按钮组每个按钮的id
yn_group.addButton(rb_y, 1);
"""如果不传入id,系统会从-1开始自动分配id。所以手动传入的id一定不能为负数(尤其不能是-1)以免引起冲突"""

# 获取按钮
print(yn_group.buttons())  # 获取某一组的所有按钮
print(yn_group.button(1))  # 获取id=1的按钮,这个需要在之前设置id
print(sex_group.checkedButton())  # 获取被选中的按钮

# 移除按钮(只是移除关系,而不是真正删除这个按钮)
sex_group.removeButton(rb_f)

# 设置id的第二种方法
sex_group.setId(rb_m, 100)
sex_group.setId(rb_f, 101)

# 获取id
print('sex_group组的rb_f的id为:', sex_group.id(rb_f))
print('sex_group组被选中按钮的id为:', sex_group.checkedId())

# 设置互斥性
yn_group.setExclusive(True)
# 获取互斥性
print('yn_group组的互斥性为;', yn_group.exclusive())

# 信号监听:两种方式获取被点击按钮的id
yn_group.buttonClicked.connect(lambda var: print('yn_group组被点击按钮的id为:', yn_group.id(var)))
yn_group.buttonClicked[int].connect(lambda var: print('yn_group组被点击按钮的id为:', var))

在这里插入图片描述

信号

rb_f = QRadioButton('女', self)
# 切换选中的信号
rb_f.toggled.connect(lambda isCheacked: print('女被选中:', isCheacked))

QCheckBox

排他性

for i in range(3):
    cb = QCheckBox(self)
    cb.setText(str(i))
    cb.move(100, 0 + 50 * i)

    # 获取排他性
    print('默认排他性:', cb.autoExclusive())
    # 设置排他性
    cb.setAutoExclusive(True)

在这里插入图片描述
在这里插入图片描述

三态

cb = QCheckBox('Unity', self)
cb.setIcon(QIcon('./resources/unity.png'))
cb.setIconSize(QSize(40, 40))

# 设置三态
cb.setTristate(True)
# 获取是否为三态
print('当前为三态?', cb.isTristate())

# 设置默认选中状态
"""Qt.Checked			# 选中
Qt.Unchecked			# 取消选中
Qt.PartiallyChecked		# 部分选中"""
cb.setCheckState(Qt.PartiallyChecked)

# 监听信号
cb.stateChanged.connect(lambda state: print('三态的状态为:', state))  # 三态状态:0 -> 未选中,1 -> 部分选中,2 -> 选中
cb.toggled.connect(lambda isChecked: print('二态的状态为:', isChecked))  # 二态状态,只有False和True,系统认为选中和部分选中都为True

在这里插入图片描述

QToolButton

认识

tb = QToolButton(self)

# 如果既设置了图标,又设置了文本,它只会显示图标,因为工具栏一般显示的是图标而非文本
tb.setIcon(QIcon('./resources/unity.png'))
tb.setIconSize(QSize(100, 100))
tb.setText("工具按钮")

# 设置提示文本,即鼠标移动到图标1秒后会提示该工具的功能
tb.setToolTip('这是提示信息')

# 设置文本图标显示风格
"""Qt.ToolButtonIconOnly		#仅显示图标
Qt.ToolButtonTextOnly			#仅显示文本
Qt.ToolButtonTextBesideIcon		#文本显示在图标旁边
Qt.ToolButtonTextUnderIcon		#文本显示在图标下方
Qt.ToolButtonFollowStyle		#按照默认风格显示"""
tb.setToolButtonStyle(Qt.ToolButtonIconOnly)

在这里插入图片描述

箭头图标

tb = QToolButton(self)

# 设置箭头类型
"""Qt.NoArrow	0
Qt.Uparrow		1
Qt.DownArrow	2
Qt.LeftArrow	3
Qt.RightArrow	4"""
tb.setArrowType(Qt.RightArrow)

# 获取箭头类型
print(tb.arrowType())
"""注意,如果既有箭头,又有图标,还有文本。当显示风格为仅图标,
则会显示箭头而不是自定义图标。所以,箭头的优先级更高"""

在这里插入图片描述

自动提升

QPushButton做不到

tb = QToolButton(self)
tb.setArrowType(Qt.RightArrow)

# 设置自动提升
tb.setAutoRaise(True)
# 获取是否为自动提升
print(tb.autoRaise())

在这里插入图片描述

菜单和弹出模式

tb = QToolButton(self)
tb.setIcon(QIcon('./resources/unity.png'))
tb.setIconSize(QSize(50, 50))

# 设置菜单(方法同QPushButton)
menu = QMenu(tb)
new_action = QAction(QIcon('./resources/pink_flower.png'), '新建', menu) 
open_action = QAction(QIcon('./resources/blue_flower.png'), '打开', menu)
quit_action = QAction(QIcon('./resources/red_flower.png'), '退出', menu)
child_menu = QMenu(menu)
child_menu.setTitle('子菜单')
child_action = QAction('子行为', child_menu)
child_menu.addAction(child_action)
menu.addAction(new_action)
menu.addAction(open_action)
menu.addMenu(child_menu)
menu.addSeparator()
menu.addAction(quit_action)
tb.setMenu(menu)

# 设置弹出方式
"""QToolButton.DelayedPopup	# 延迟显示(默认),鼠标一直点击按钮1秒才会弹出菜单。长按会阻挡信号的发射
QToolButton.MenuButtonPopup	# 产生一个专门的指示箭头,点击这个箭头才可以。点击这个箭头也会阻挡信号的发射
QToolButton.InstantPopup	# 点击按钮就显示,但会完全阻断信号的发射"""
tb.setPopupMode(QToolButton.InstantPopup)

# 监听行为
new_action.setData('新建行为的data')	#给行为传入不同的数据,以后信号监听时用于区分它
open_action.setData('打开行为的data')
quit_action.setData('退出行为的data')
def func(action):
	print('某个行为',action.data())
tb.triggered.connect(func)

在这里插入图片描述

QCommandLinkButton

# 实例化对象时可利用构造函数设置属性
btn = QCommandLinkButton('标题', '描述', self)
# 设置图标,默认是右箭头
btn.setIcon(QIcon('./resources/big_flower.png'))
# 设置新的标题和描述
btn.setText('新的标题')
btn.setDescription('新的描述')

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值