pyQt5 学习笔记(12)QPushButton 按钮控件

  • Post author:
  • Post category:其他

一 、QPushButton 简介

QPushButton 控件是一个非常常用的按钮控件,它继承自QABstractButton。
在这里插入图片描述

二、构造函数

QPushButton 可以设置父控件,图标以及显示的文本,如果创建对象时已经确定,可通过构造函数快捷创建,关于QPushButton的详情,可参考Qt官方文档:QPushButton
以下列出QpushButton的构造函数:

  • QPushButton(const QIcon &icon, const QString &text, QWidget *parent = nullptr)
  • QPushButton(const QString &text, QWidget *parent = nullptr)
  • QPushButton(QWidget *parent = nullptr)

创建对象时,请注意对应参数的位置,以第1个构造函数为例:

from PyQt5.Qt import *
import sys

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

w = QWidget()
w.setWindowTitle("QPushButton")
w.resize(300,300)
#创建一个按钮,图标为:powerBtn;文本为:关机;父控件为:w
btn = QPushButton(QIcon("powerBtn"),"关机",w)
w.show()

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

运行:
在这里插入图片描述
注意到,这里有3个参数,分别为图标对象,文本以及父控件,它们的顺序是根据构造函数QPushButton(const QIcon &icon, const QString &text, QWidget *parent = nullptr)来确定的。其他控件同理。

三、功能(API)

接下来是QPushButton特有的功能的介绍。

1. 菜单(menu)功能

通常菜单栏的按钮,都会是一个菜单按钮,点击它们以后会弹出相关的一个菜单,提供更多的功能供用户选择:
在这里插入图片描述
如上图所示,Navigate 菜单列表中有不同的项,如类似Line/Column… 按钮,当它被按下时候,直接执行动作,这种项被称为Action,而有的则是Bookmarks 按钮,它不直接执行动作,而是弹出另一个菜单,它被称为子菜单。

1.1 添加一个Action

首先示例如何添加一个 Aciton 到菜单中:

from PyQt5.Qt import *
import sys

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

#1.创建QWidget控件
w = QWidget()
w.setWindowTitle("QPushButton")
w.resize(300,300)

#2.创建一个QPushButton控件
btn = QPushButton(QIcon("menu"),"菜单",w)

#3.创建一个菜单对象
menu = QMenu()

#4.QAction()对象
new_action = QAction()                  #创建对象
new_action.setText("关机")              #设置文本
new_action.setIcon(QIcon("powerBtn"))  #设置图标
new_action.triggered.connect(lambda:print("关机"))

menu.addAction(new_action)             #将图标添加到菜单中
btn.setMenu(menu)                      #将菜单添加到按键中

#5. 窗口显示
w.show()

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

运行:
在这里插入图片描述

上文使用addAction来添加一个动作(Action),也可以通过 addActions 来添加多个动作。

QPushButton 由于添加了菜单,固右侧多了一个三角形,当按键 “菜单” 被点击时候,弹出一个菜单,里面只有一个 Action(关机),因为将Action的信号连接是匿名函数(print("关机")),所以,当“关机”被点击时候,会打印出对应的语句。
在按钮中添加一个菜单只需要通过setMenu()函数即可,参数为Menu对象。而Menu则可以添加QAction,子菜单,分割线等等。

1.2 添加一个子菜单

添加子菜单就是在一个菜单(Menu)中,再添加一个菜单(Menu):

from PyQt5.Qt import *
import sys

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

#1.创建QWidget控件
w = QWidget()
w.setWindowTitle("QPushButton")
w.resize(300,300)

#2.创建一个QPushButton控件
btn = QPushButton(QIcon("menu"),"菜单",w)

#3.创建一个菜单对象
menu = QMenu()

#4.QAction()对象
new_action = QAction()                 #创建对象
new_action.setText("关机")             #设置文本
new_action.setIcon(QIcon("powerBtn"))  #设置图标
new_action.triggered.connect(lambda:print("关机"))

menu.addAction(new_action)             #将图标添加到菜单中

#5. 设置一个子菜单
sub_menu = QMenu(menu)
sub_menu.setTitle("子菜单")
sub_action = QAction()
sub_action.setText("子菜单-关机")
sub_action.setIcon(QIcon("powerBtn"))
sub_action.triggered.connect(lambda:print("子菜单:关机"))
sub_menu.addAction(sub_action)             #将图标添加到菜单中

#6.添加子菜单
menu.addMenu(sub_menu)
btn.setMenu(menu)                          #将菜单添加到按键中

#7. 窗口显示
w.show()

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

运行:
在这里插入图片描述
程序按创建菜单的方式创建了一个新的菜单对象:sub_menu,接着将其添加到原本的菜单即可完成子菜单的添加。

1.3 添加一个分割线

菜单中一般有多个项目,它们可能有明显的分类,可以通过添加分割线来让菜单更加有条理,添加分割线的API为:addSeparator()

from PyQt5.Qt import *
import sys

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

#1.创建QWidget控件
w = QWidget()
w.setWindowTitle("QPushButton")
w.resize(300,300)

#2.创建一个QPushButton控件
btn = QPushButton(QIcon("menu"),"菜单",w)

#3.创建一个菜单对象
menu = QMenu()

#4.QAction()对象
open_action = QAction("打开文件")                  #创建对象
close_action = QAction("关闭文件")                  #创建对象
Eidt_action = QAction("编辑文件")                  #创建对象
Exit_action = QAction("退出")

#5.添加多个Action
menu.addActions([open_action,close_action,Eidt_action])                    #将图标添加到菜单中
menu.addSeparator()    # 添加分割线
menu.addAction(Exit_action) #添加退出Aciton

btn.setMenu(menu)
#6. 窗口显示
w.show()

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

运行:
在这里插入图片描述
第25行:通过addActions添加多个Action,注意到,多个Action是集合成一个元组的方式。
第26行;添加一个分割线
第27行;添加退出Action

所以,分割线就将“打开文件”,“关闭文件”,“编辑文件”和“退出”分割开来。

1.4 显示菜单

我们可以通过程序来主动显示菜单,不需要用户点击,其API为:showMenu

from PyQt5.Qt import *
import sys

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

#1.创建QWidget控件
w = QWidget()
w.setWindowTitle("QPushButton")
w.resize(300,300)

#2.创建一个QPushButton控件
btn = QPushButton(QIcon("menu"),"菜单",w)

#3.创建一个菜单对象
menu = QMenu()

#4.QAction()对象
open_action = QAction("打开文件")                  #创建对象
close_action = QAction("关闭文件")                  #创建对象
Eidt_action = QAction("编辑文件")                  #创建对象
Exit_action = QAction("退出")

#5.添加多个Action
menu.addActions([open_action,close_action,Eidt_action])                       #将图标添加到菜单中
menu.addSeparator()
menu.addAction(Exit_action)

btn.setMenu(menu)
#5. 窗口显示
w.show()
btn.showMenu()

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

这个程序只是在上[#1.3]程序中添加一句 btn.showMenu(),如此,程序运行以后,菜单就已经是打开的状态。注意到,它是添加在w.show()之后的,这是由于Menu对象是可以直接显示的,所以需要窗体显示以后再显示,否则会出现非预期显示效果。
如果我们要设计一个按钮,类似CSDN的消息按钮,当光标移动上去以后主动显示一个菜单,就可以使用这个功能,这里可以使用控件的enterEvent()槽函数来捕获光标的移入事件,然后主动调用showMenu()函数即可。以下程序示例了这种效果:

from PyQt5.Qt import *
import sys

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

#1.创建QWidget控件
w = QWidget()
w.setWindowTitle("QPushButton")
w.resize(300,300)

#自定义一个Btn类
class Btn(QPushButton):
    #重写移入事件
    def enterEvent(self, *args, **kwargs):
        test()

#2.创建一个QPushButton控件
btn = Btn(QIcon("menu"),"菜单",w)

#3.创建一个菜单对象
menu = QMenu()

#4.QAction()对象
open_action = QAction("打开文件")                  #创建对象
close_action = QAction("关闭文件")                  #创建对象
Eidt_action = QAction("编辑文件")                  #创建对象
Exit_action = QAction("退出")

#5.添加多个Action
menu.addActions([open_action,close_action,Eidt_action])                       #将图标添加到菜单中
menu.addSeparator()
menu.addAction(Exit_action)

btn.setMenu(menu)
#5. 窗口显示
w.show()

# 显示菜单
def test():
    btn.showMenu()

运行:
在这里插入图片描述
为了突出逻辑,这里尽量少的修改程序达到效果,实际编程请不要使用这种方式,太过随意的编程会给后续程序在维护和稳定性上都造成不小的隐患。

2. 扁平化

扁平化不绘制按钮的背景颜色和边框,看起来就像和父控件在一个平面上,通过setFlat()来设置:

from PyQt5.Qt import *
import sys

app = QApplication(sys.argv)

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

btn = QPushButton(QIcon("menu"),"菜单",w)

# 设置扁平
btn.setFlat(True)

w.show()

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

运行:
在这里插入图片描述

四、信号

1. 上下文请求(右键菜单)

右键菜单指的是控件被右键点击时候,弹出的菜单。比如,在浏览器的收藏中,右键其中一个,如下图所示:
在这里插入图片描述
注意到,这里指的是“控件”而非只有按键,所以这个功能严格来说并不属于QPushButton控件的内容。
在pyQt中,右键菜单有两种策略,默认的策略需要重写方法,另一种用户自定义策略则是当控件被右键单击时,调用一个自定义的函数,这里只示例后者:

# 0. 导入需要的包和模块
from PyQt5.Qt import *
import sys

# 1. 创建一个应用程序对象
app = QApplication(sys.argv)

w = QWidget()
w.setWindowTitle("右键菜单")
w.resize(500, 500)

menu = QMenu(w)

btn = QPushButton("菜单",w)

def show_menu(point):
    # 创建一个菜单
    menu = QMenu(btn)
    # 创建另一个菜单,作为子菜单
    sub_menu = QMenu("编辑",menu)
    # 创建Aciton
    new_action = QAction("新建", menu)
    open_action = QAction("打开", menu)
    exit_action = QAction("退出", menu)
    copy_action = QAction("复制",sub_menu)
    # 添加菜单项
    menu.addAction(new_action)
    menu.addAction(open_action)
    sub_menu.addAction(copy_action)
    menu.addMenu(sub_menu)
    menu.addSeparator()
    menu.addAction(exit_action)

    #坐标转换
    dest_point = w.mapToGlobal(point)
    #在dest_point处弹出菜单
    menu.exec_(dest_point)

# 设置上下文策略为:自定义
btn.setContextMenuPolicy(Qt.CustomContextMenu)
# 连接上下文请求
btn.customContextMenuRequested.connect(show_menu)

w.show()
sys.exit(app.exec_())

运行:
在这里插入图片描述
当光标在按键 “菜单” 右键时,将弹出一个右键菜单。
第40行:设置右键菜单策略为用户自定义
第41行:将右键菜单请求连接show_menu()函数,这需要右键菜单策略为自定义
第16行:创建一个显示菜单的函数,用来响应按键被右击
第35~36行:当右键“菜单”按键时,该控件发送一个带参数的请求,该参数为此刻光标的相对坐标(相对控件的坐标),而第36行,exec_()函数参数为绝对坐标(相对屏幕的坐标),所以需要mapToGlobal()将函数做一次转换。


版权声明:本文为qq_17351161原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。