Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说9 - 具化的按钮子类,希望能够帮助你!!!。
用来给用户点击, 来完成某种动作的控件,一般是矩形。
例如:登录按钮、注册按钮、关闭按钮、是、否…
QObject——QWidget——QAbstractButton——QPushButton
btn1 = QPushButton(window)
btn2 = QPushButton("按钮", window)
btn3 = QPushButton(QIcon("star.png"), "按钮", window)
btn2.move(0, 100)
btn3.move(0, 200)
设置英文文本时使用&符号
QPushButton("&Sz", window)
setText("&Sz")
想通过快捷键触发按钮点击事件的时候设置
创建一个窗口, 上面有个子控件按钮,要求:点击后打印"Hello Sz",可通过快捷键Alt + H, 触发点击。
btn = QPushButton("&H", window)
btn.pressed.connect(lambda : print("Hello Sz"))
可以设置点击按钮是弹出的菜单, 供用户选择。比如:
对应上图,QMenu:
# *******************设置菜单*******************开始
menu = QMenu()
new_action = QAction()
new_action.setText("新建")
new_action.setIcon(QIcon("star.png"))
menu.addAction(new_action)
btn3.setMenu(menu)
# *******************设置菜单*******************结束
由构造函数可知:
class QAction(__PyQt5_QtCore.QObject):
""" QAction(parent: QObject = None) QAction(str, parent: QObject = None) QAction(QIcon, str, parent: QObject = None) """
创建QAction同时可设置标题、图标、父对象,即可以合并成一句:
注意:就算设置了父控件,也不会自动加到菜单里,还得手动add。
# *******************设置菜单*******************开始
menu = QMenu(window)
new_action = QAction(QIcon("star.png"), "新建", menu)
menu.addAction(new_action)
btn3.setMenu(menu)
# *******************设置菜单*******************结束
创建一个菜单,其中最近打开包含子菜单,新建、打开–分割线–退出不包含。
# *******************设置菜单*******************开始
menu = QMenu(window)
# new_action = QAction()
# new_action.setText("新建")
# new_action.setIcon(QIcon("star.png"))
new_action = QAction("新建", menu)
new_action.triggered.connect(lambda: print("新建文件"))
open_action = QAction("打开", menu)
open_action.triggered.connect(lambda: print("打开文件"))
exit_action = QAction("退出", menu)
exit_action.triggered.connect(lambda: print("退出程序"))
open_recent_menu = QMenu("最近打开", menu)
# open_recent_menu.setTitle("最近打开")
file_action = QAction("python-gui")
open_recent_menu.addAction(file_action)
menu.addAction(new_action)
menu.addAction(open_action)
menu.addMenu(open_recent_menu)
menu.addSeparator()
menu.addAction(exit_action)
btn3.setMenu(menu)
print(btn3.menu())
# *******************设置菜单*******************结束
打印出的菜单对象:<PyQt5.QtWidgets.QMenu object at 0x00000149EB06D0D8>
# *******************扁平化*******************开始
print(btn3.isFlat())
btn3.setStyleSheet("background-color:cyan;")
btn3.setFlat(True)
print(btn3.isFlat())
# *******************扁平化*******************结束
输出:False、True。
非扁平化:(看第三个按钮)
扁平化:
设置按钮扁平化风格。
# *******************自动默认按钮*******************开始
btn2.setAutoDefault(True)
btn1.setDefault(True)
print(btn1.isDefault())
print(btn2.isDefault())
print(btn3.isDefault())
print(btn1.autoDefault())
print(btn2.autoDefault())
print(btn3.autoDefault())
# *******************自动默认按钮*******************结束
输出:True,False,False;False,True,False。
一般是在对话框中使用。比如下图的自动默认按钮是【打开】,即点击==【Enter】==会选择的按钮。
都是继承下来的。
QAbstractButton:
QWidget:
PS:设置上下文菜单的函数是setContextMenuPolicy(参数),其中参数有如下两种:
默认:
class Window(QWidget):
def contextMenuEvent(self, evt):
# *******************设置菜单*******************开始
menu = QMenu(self)
new_action = QAction("新建", menu)
new_action.triggered.connect(lambda: print("新建文件"))
open_action = QAction("打开", menu)
open_action.triggered.connect(lambda: print("打开文件"))
exit_action = QAction("退出", menu)
exit_action.triggered.connect(lambda: print("退出程序"))
open_recent_menu = QMenu("最近打开", menu)
# open_recent_menu.setTitle("最近打开")
file_action = QAction("python-gui")
open_recent_menu.addAction(file_action)
menu.addAction(new_action)
menu.addAction(open_action)
menu.addMenu(open_recent_menu)
menu.addSeparator()
menu.addAction(exit_action)
menu.exec_(evt.globalPos())
# *******************设置菜单*******************结束
自定义:
# *******************自定义上下文菜单*******************开始
def show_menu(point):
# *******************设置菜单*******************开始
menu = QMenu(window)
new_action = QAction("新建", menu)
new_action.triggered.connect(lambda: print("新建文件"))
open_action = QAction("打开", menu)
open_action.triggered.connect(lambda: print("打开文件"))
exit_action = QAction("退出", menu)
exit_action.triggered.connect(lambda: print("退出程序"))
open_recent_menu = QMenu("最近打开", menu)
# open_recent_menu.setTitle("最近打开")
file_action = QAction("python-gui")
open_recent_menu.addAction(file_action)
menu.addAction(new_action)
menu.addAction(open_action)
menu.addMenu(open_recent_menu)
menu.addSeparator()
menu.addAction(exit_action)
# 局部-->全局
dest_point = window.mapToGlobal(point)
menu.exec_(dest_point)
# *******************设置菜单*******************结束
window.setContextMenuPolicy(Qt.CustomContextMenu)
window.customContextMenuRequested.connect(show_menu)
# *******************上下文菜单*******************结束
注意:menu.exec_(QPoint)获取的是相对于桌面的坐标,所以获取鼠标位置也应该是全局位置。在默认那里全局位置直接通过事件的globalPos()方法来获得,在自定义那里发射信号传出来的是局部坐标(可以通过槽函数接收参数并打印得知),需要映射方法window.mapToGlobal(point)。
命令链接是Windows Vista引入的新控件;
它的用途类似于单选按钮的用途,因为它用于在一组互斥选项之间进行选择;
命令链接按钮不应单独使用,而应作为向导和对话框中单选按钮的替代选项;
外观通常类似于**平面按钮(扁平化)**的外观,但除了普通按钮文本之外,它还允许描述性文本。
QObject——QWidget——QAbstractButton——QPushButton——QCommandLinkButton
btn = QCommandLinkButton("标题", "描述", window)
btn = QCommandLinkButton("标题", "描述", window)
btn.setText("新的标题就是")
btn.setDescription("这个链接按钮功能不多欸")
btn.setIcon(QIcon("star.png"))
同QPushButton
一般用于给用户提供若干选项中的单选操作,比如:性别不是男就是女;判断题答案不是是就是否…当选中一个时, 会自动取消上一个。此按钮左侧会有一个圆圈图标,用于标识用户的选中状态。
QObject——QWidget——QAbstractButton——QRadioButton
QRadioButton(parent)
QRadioButton(text, parent)
rb_man = QRadioButton("男", window)
rb_man.move(100, 100)
rb_woman = QRadioButton("女", window)
rb_woman.move(100, 150)
如果只有一个单选按钮,可选可不选;如果同组有两个及以上,至少得选一个。
setIcon(QIcon):设置图标
rb_man.setIcon(QIcon("star.png"))
rb_man.setIconSize(QSize(60, 60))
# 设置默认选中的按钮
rb_woman.setChecked(True)
setShortcut():
设置快捷键
rb_man.setShortcut("Alt+M")
借助&(必须是按钮标题里含有的字母)
rb_man = QRadioButton("男-&Man", window)
均继承自父类(pressed、released、clicked、toggled)
常用信号为:toggled(bool)切换信号
rb_woman.toggled.connect(lambda ischecked: print(ischecked))
# *******************多组互斥问题*******************开始
rb_man = QRadioButton("男", window)
rb_man.move(100, 100)
rb_woman = QRadioButton("女", window)
rb_woman.move(100, 150)
rb_yes = QRadioButton("yes", window)
rb_no = QRadioButton("no", window)
rb_yes.move(200, 100)
rb_no.move(200, 150)
# *******************多组互斥问题*******************结束
四个按钮都互斥:
解决方法一:不要放在同一个父控件内
# *******************多组互斥问题*******************开始
red = QWidget(window)
red.resize(200, 200)
red.setStyleSheet("background-color:red")
red.move(50, 50)
green = QWidget(window)
green.resize(200, 200)
green.setStyleSheet("background-color:green")
green.move(270, 50)
rb_man = QRadioButton("男", red)
rb_man.move(10, 10)
rb_woman = QRadioButton("女", red)
rb_woman.move(10, 50)
rb_yes = QRadioButton("yes", green)
rb_no = QRadioButton("no", green)
rb_yes.move(10, 10)
rb_no.move(10, 50)
# *******************多组互斥问题*******************结束
解决方法二:抽象按钮组QButtonGroup
提供一个抽象的按钮容器,可以将多个按钮划分为一组。不具备可视化的效果,一般放的都是可以被检查的按钮。
QObject——QButtonGroup
这也是为什么不可视化,QWidget是所有可视化控件的基类。
应用场景:向按钮组中添加按钮, 并选择性设置ID。
# *******************按钮组*******************开始
r_male = QRadioButton("男", window)
r_female = QRadioButton("女", window)
r_male.move(100, 100)
r_female.move(100, 150)
r_yes = QRadioButton("是", window)
r_no = QRadioButton("否", window)
r_yes.move(300, 100)
r_no.move(300, 150)
sex_group = QButtonGroup(window)
sex_group.addButton(r_male)
sex_group.addButton(r_female)
yes_group = QButtonGroup(window)
yes_group.addButton(r_yes)
yes_group.addButton(r_no)
# *******************按钮组*******************结束
buttons():查看所有按钮组中的按钮;
print(sex_group.buttons())
输出:[<PyQt5.QtWidgets.QRadioButton object at 0x0000020812A0EEE8>, <PyQt5.QtWidgets.QRadioButton object at 0x0000020812A0EF78>]
button(ID):根据ID获取对应按钮, 没有则返回None;
sex_group.addButton(r_male, 1)
sex_group.addButton(r_female, 2)
print(sex_group.button(2))
输出:<PyQt5.QtWidgets.QRadioButton object at 0x0000020812A0EF78>
checkedButton():获取选中的那个按钮。
r_male.setChecked(True)
print(sex_group.checkedButton())
输出:<PyQt5.QtWidgets.QRadioButton object at 0x0000020812A0EEE8>
应用场景:获取指定条件的按钮。
应用场景:移除指定按钮组关系,不是从界面上移除,是从抽象关系上移除。
sex_group.removeButton(r_female)
print(sex_group.buttons())
print(sex_group.button(2))
输出:[<PyQt5.QtWidgets.QRadioButton object at 0x000001A8E72BEEE8>] ;None
应用场景:设置ID, 方便识别用户选项。
# *******************绑定和获取ID*******************开始
yes_group.setId(r_yes, 1)
yes_group.setId(r_no, 2)
print(yes_group.id(r_no))
print(yes_group.id(r_yes))
print(yes_group.id(r_male))
print(yes_group.checkedId())
r_yes.setChecked(True)
print(yes_group.checkedId())
# *******************绑定和获取ID*******************结束
输出:2、1、-1、-1、1
应用场景:统一设置按钮组中的按钮是否是独占(选择互斥)
sex_group.setExclusive(False)
sex_group:可都选,可选任一,可不选。
# *******************信号*******************开始
def test(val):
print(val)
sex_group.buttonClicked.connect(test)
# *******************信号*******************结束
输出的是这样的:<PyQt5.QtWidgets.QRadioButton object at 0x000001CD6C20AF78>
重点注意:
参数可以是整型也可以是按钮,整型代表ID。
如果一个对象向外界提供的信号名称一样,但参数不一样,可以使用如下格式进行选择:
signal_name[type] 表示 信号名称[参数类型]
所以如果先要输出按钮ID,有两种方法:
方法一:直接接收int型
sex_group.buttonClicked[int].connect(test)
方法二:在槽函数中获取id
def test(val):
print(sex_group.id(val))
一般用于给用户提供若干选项中的多选操作,可以都选,也可以都不选,也可以选部分。左侧会有一个方框图标, 标识用户的选中状态。
QObject——QWidget——QAbstractButton——QCheckBox
查看父类除了看定义,还可以直接打印print(QCheckBox.__bases__)
应用场景:是否支持复选框展示三种状态(未选中、部分选中、选中)
应用场景:想给用户多一种选择状态
除了继承的,特有:
cb = QCheckBox("python", window)
cb.setTristate(True)
cb.stateChanged.connect(lambda state: print(state))
提供了一个快速访问按钮,通常是在工具栏内部使用,工具按钮通常不显示文本标签,而是显示图标。
QObject——QWidget——QAbstractButton——QToolButton
QToolButton(parent: QWidget = None)
注意:如果文本和图标同时设置, 则默认只展示图标。
btn = QToolButton(window)
btn.setText("工具栏")
btn.setIcon(QIcon("star.png"))
btn.setIconSize(QSize(60, 60))
btn.setToolTip("新建按钮")
setToolButtonStyle(Qt.ToolButtonStyle(可选如下)):风格取值
Qt.ToolButtonIconOnly:仅显示图标
Qt.ToolButtonTextOnly:仅显示文字
Qt.ToolButtonTextBesideIcon:文本显示在图标旁边
Qt.ToolButtonTextUnderIcon:文本显示在图标下方
Qt.ToolButtonFollowStyle:遵循风格(不管)
toolButtonStyle():获取样式,可手动打印。
setArrowType(Qt.ArrowType(同上,也是个枚举类型))
Qt.NoArrow:无箭头
Qt.UpArrow:向上箭头
Qt.DownArrow:向下箭头
Qt.LeftArrow:向左箭头
Qt.RightArrow:向右箭头
arrowType():获取箭头类型。
PS:箭头优先级高于图标。
应用场景:
在自动提升模式下,该按钮仅在鼠标指向时才会绘制3D帧(突起),在工具栏(QToolBar)中默认就是自动提升。
一般按钮(QPushButton):如果设置了扁平化,不管鼠标放不放上去,都是扁平;但如果不设置扁平化,鼠标不移过去也是突起状态,移过去发光。
工具按钮:没有扁平化这个设置。如果设置了自动提升,不易过去是扁平化,移过去是发光,更加美观;如果没有设置自动提升,同没有设置扁平化的一般按钮。
应用场景:通过菜单展示更多选项
setPopupMode(QToolButton.ToolButtonPopupMode)
QToolButton.DelayedPopup:默认,鼠标按住一会才显示。
实际应用:类似于浏览器后退按钮,按住停一会后不会后退,而是显示如下
QToolButton.MenuButtonPopup:有一个专门的指示箭头,点击箭头才显示。
QToolButton.InstantPopup:点了按钮就显示。
延迟弹出 | 分割线 | 发射单击信号 | |
---|---|---|---|
QToolButton.DelayedPopup | 是 | 无 | 否 |
QToolButton.MenuButtonPopup | 否 | 有 | 是 |
QToolButton.InstantPopup | 否 | 无 | 否 |
有分割线时:点击右边的箭头是弹出菜单,点击左边是触发单击。
popupMode()
应用场景:设置菜单弹出的触发方式。
除了继承的,只有一个是特有的,是原来的triggered信号重写得到的。
triggered(QAction *action):当点击某个action时触发,并会将action传递出来。
QAction对象可以通过==setData(Any)==绑定数据,==data()==获取数据。
例1:
btn = QToolButton(window)
btn.setText("工具栏")
menu = QMenu(btn)
menu.setTitle("菜单")
sub_menu = QMenu(menu)
sub_menu.setTitle("子菜单")
sub_menu.setIcon(QIcon("star.png"))
action1 = QAction("打开1", menu)
action2 = QAction("打开2", menu)
# action1.triggered.connect(lambda: print("点击了行为菜单"))
menu.addMenu(sub_menu)
menu.addSeparator()
menu.addAction(action1)
menu.addAction(action2)
btn.setMenu(menu)
btn.setPopupMode(QToolButton.InstantPopup)
def do_action(action):
print("点击了行为", action)
btn.triggered.connect(do_action)
点击了【打开1】和【打开2】后,输出
如果想要不同的行为执行不同事件,除了每个action写一个槽函数还有什么方法?
例2:
action1.setData([1, 2, 3])
action2.setData({
"心情": "抑郁"})
def do_action(action):
print("点击了行为", action.data())
btn.triggered.connect(do_action)
输出:
这就提示我们可以给不同的行为绑定不同的数据,通过不同的数据执行不同的操作,比给每个行为单独连接信号要方便很多。
侵权即删
今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。
上一篇
已是最后文章
下一篇
已是最新文章