6 - PyQt5 基类 QObject
从上图列出的所有基类可以看到,QObject 是所有的 Qt 对象的基类。
那么,QObejct 的父类是什么呢?这就需要用到 mro。
mro:Method Resolution Order,方法解析顺序,可以打印出来类的继承顺序,也有博主提出不需要调用的解决办法。
def setup_ui(self):
self.test_inheritance()
def test_inheritance(self):
mros = QObject.mro()
for mro in mros:
print(mro)
运行结果:可以看到Qobject(pyqt 的基类)也是继承自 object (python 的基类) 。
(一)功能作用
1、对象名称,属性
API
-
setObjectName(“唯一名称”):给一个 Qt 对象设置一个名称,一般这个名称是唯一的,当做对象的 ID 来使用。
-
objectName():获取一个 Qt 对象的名称。
-
setProperty(“属性名称”,值):给一个 Qt 对象动态的添加一个属性与值。
-
property(“属性名称”):获取一个对象的属性值。
-
dynamicPropertyNames():获取一个对象中所有通过 setProperty() 设置的属性名称。
# 存放所有子控件以及子控件的配置操作 def setup_ui(self): # self.test_inheritance() self.nameandAttribute() def nameandAttribute(self): # 测试API obj = QObject() obj.setObjectName("notice") print(obj.objectName()) obj.setProperty("level1", "error") obj.setProperty("level2", "warning") print(obj.property("level1")) print(obj.dynamicPropertyNames())
运行结果:
应用场景
- 用于 qss 的 ID 选择器,属性选择器 ——> 方便统一设置样式。
- 用于装饰器的信号与槽
案例:创建多个用于信息提示的 QLabel
要求:
-
凡是提示的 QLabel 控件,都要求设置:
字体大小为 20px;
字体颜色为灰色;
边框圆角为 8px。
-
信息提示分多个级别:
正常 (normal)——绿色边框、绿色字体。
警告 (warning)——黄色边框、黄色字体。
错误 (error)——红色边框、红色字体。
涉及知识点:
- qss 样式表
- 文件读取。
- 对象 \ 属性名称设置。
先介绍一下 qss:qss 和控件的关系类似于前端 css 和 html 元素的关系。
样式相关:
def exmpleDemonstration(self):
label = QLabel(self)
label.setText("标签样式啊样式")
label.setStyleSheet("font-size: 30px; color: purple")
其中 “font-size: 30px; color: purple” 这个字符串就是用来设置标签的样式,为了开发方便,常常把字符串放到某个文件中,需要用的时候读取文件,作用到整个应用程序上,这个文件的后缀就是.qss (qss 我猜是样式表 Qt Style Sheet 的缩写)。
qss 内容:
QLabel{
background-color:yellow;
font-size: 30px;
color: black;
}
QPushButton{
background-color:red;
}
因为 qss 里面有很多样式,需要做一个选择器,很多个样式去匹配存在的控件。上面我用的是类选择器,还有很多其他选择器比如:通配符选择器、ID 选择器等等。
PyQt5 代码:
def exmpleDemonstration(self):
with open("style.qss", "r") as f:
app.setStyleSheet(f.read())
label = QLabel(self)
label.setText("标签样式啊样式")
label2 = QLabel(self)
label2.setText("第二个标签")
label2.move(100, 50)
button = QPushButton(self)
button.setText("按钮")
button.move(200, 200)
运行效果:
从运行效果可以看到,实现了从 style.qss 样式表中读取字符串,并在整个应用程序上实现,两个标签都变成了一种格式。
然后现在又出现了一个问题:如果只想使用标签怎么办,以上方法会一把子把所有的样式都给改了,这时候就要用到 ID 选择器(# ID 名称),这里的 ID 指的是前面说的 ObjectName。
设置如下:
label = QLabel(self)
label.setObjectName("notice")
label.setText("标签样式啊样式")
label2 = QLabel(self)
label.setObjectName("notice")
label2.setText("第二个标签")
label2.move(100, 50)
label3 = QLabel(self)
label3.setText("想要普通显示的部分")
label3.move(400, 50)
QLabel#notice{
background-color:yellow;
font-size: 30px;
color: black;
}
测试结果:
可以看到只有对象名称为 notice 的才会被修改样式,label3 还是默认样式。
解决了这一个问题,还有问题是如何给 label 和 label2 设置不同样式,因为现实生活中同样是 notice,有的提示正确信息,有的提示错误信息,还需要样式区分,这时候需要属性选择器。
qss 设置:
其中 border 设定边框为 1 像素宽,实线,颜色使用 gray 来表达。radius 表示半径,也就是圆角。
px 表示像素(Pixel),是相对电脑分辨率谈的长度单位,和实际无关。
QLabel#notice {
font-size: 20px;
color: gray;
border: 1px solid gray;
border-radius: 8px;
}
QLabel#notice[noticelevel="normal"] {
color: green;
border-color: green;
}
QLabel#notice[noticelevel="warning"] {
color: yellow;
border-color: yellow;
}
QLabel#notice[noticelevel="error"] {
color: red;
border-color: red;
}
python 代码:
label = QLabel(self)
label.setObjectName("notice")
label.setText("没有任何地位的通知")
label2 = QLabel(self)
label2.setObjectName("notice")
label2.setProperty("noticelevel", "warning")
label2.setText("效率变低啦")
label2.move(100, 50)
button = QPushButton(self)
button.setText("默默路过的按钮")
button.move(200, 200)
label3 = QLabel(self)
label3.setObjectName("notice")
label3.setProperty("noticelevel", "error")
label3.setText("被退学了")
label3.move(400, 50)
label3 = QLabel(self)
label3.setObjectName("notice")
label3.setProperty("noticelevel", "normal")
label3.setText("无事发生")
label3.move(50, 300)
noticelevel 是属性名,normal、warning、error是属性的值。
实现效果:
到这儿就基本实现了案例的要求。
2、父子对象的操作
API(Application Programming Interface,应用程序接口)
-
setParent(parent):设置父对象,父对象只能设置一个,设置多个会被新设置的给覆盖掉。给谁设置父对象,就调用谁的 setParent()。
尝试构造如下父子关系图:
def parentandChildren(self):
obj0 = QObject()
obj1 = QObject()
obj2 = QObject()
obj3 = QObject()
obj4 = QObject()
obj5 = QObject()
obj1.setParent(obj0)
obj2.setParent(obj0