您的位置:首页 > 其它

对setStyleSheet的一点入门探索

2017-10-18 10:46 387 查看
最近学习pyqt教程(http://zetcode.com/gui/pyqt5/)到dialog章节时碰到一个疑问,先附上教程中的源码:

colordialog.py

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial

In this example, we select a color value
from the QColorDialog and change the background
color of a QFrame widget.

Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
"""

from PyQt5.QtWidgets import (QWidget, QPushButton, QFrame,
QColorDialog, QApplication)
from PyQt5.QtGui import QColor
import sys

class Example(QWidget):

def __init__(self):
super().__init__()

self.initUI()

def initUI(self):

col = QColor(0, 0, 0)

self.btn = QPushButton('Dialog', self)
self.btn.move(20, 20)

self.btn.clicked.connect(self.showDialog)

self.frm = QFrame(self)
self.frm.setStyleSheet("QWidget { background-color: %s }"
% col.name())
self.frm.setGeometry(130, 22, 100, 100)

self.setGeometry(300, 300, 250, 180)
self.setWindowTitle('Color dialog')
self.show()

def showDialog(self):

col = QColorDialog.getColor()

if col.isValid():
self.frm.setStyleSheet("QWidget { background-color: %s }"
% col.name())

if __name__ == '__main__':

app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())


我的疑问在initUI函数这里:

self.frm.setStyleSheet("QWidget { background-color: %s }"
% col.name())
为什么frm设置样式时用的参数是父类QWidget而不是QFrame?这里的frm和QWidget到底是什么关系?

为了搞清楚这个问题,遂作以下尝试:

1. 将frm设置样式的类参数改为QFrame

self.frm.setStyleSheet('QFrame{ background-color: %s }'
% col.name())
重新运行,看到的效果与原来一样:



2. 将frm设置样式的类参数改为QPushButton

self.frm.setStyleSheet('QPushButton{ background-color: %s }'
% col.name())
重新运行,发现对frm设置背景色未生效:



于是猜测:frm样式参数中的QWidget或QFrame或QPushButton起着类似“作用域”的作用。对于frm对象而言,它是属于QFrame类的,而QFrame属于QWidget子类,因此,“作用域”设置为QFrame和QWidget都能成功使背景色生效于frm;而frm对象不属于QPushButton类,因此“作用域”为QPushButton不能使背景色生效于frm。
姑且称样式参数中的QWidget或QFrame或QPushButton为“selector”,那么frm和selector之间是否必须具备类继承关系才能使frm样式生效呢?为了验证这点,同时进一步验证以上猜测,继续以下尝试:

3. 通过顶层对象self进行样式设置
3.1 为了便于观察效果,在unitUI中注释掉frm对象对样式方法的调用,并针对self追加样式设定语句:

def initUI(self):

#通过设定rgb值来控制颜色
col = QColor(0, 0, 0)

self.btn = QPushButton('Dialog', self)
self.btn.move(20, 20)
self.btn.clicked.connect(self.showDialog)

self.frm = QFrame(self)
'''self.frm.setStyleSheet('QWidget { background-color: %s }'
% col.name())'''
self.frm.setGeometry(130, 22, 100, 100)

self.setGeometry(300, 300, 250, 180)
self.setWindowTitle('Color dialog')
self.show()

self.setStyleSheet('QWidget { background-color: rgb(0, 0, 0) }'
'QFrame { background-color: rgb(255, 255, 255) }'
'QPushButton { background-color: rgb(0, 255, 0) }'
)
重新运行,主窗体、frm及btn背景色分别为黑、白、绿:



3.2 将对QPushButton对象设定样式的语句注释掉:

self.setStyleSheet('QWidget { background-color: rgb(0, 0, 0) }'
'QFrame { background-color: rgb(255, 255, 255) }'
#'QPushButton { background-color: rgb(0, 255, 0) }'
)
重新运行,此时btn颜色被设定为与主体窗一致的黑色,frm保持白色:



3.3 进一步将对QFrame对象设定样式的语句也注释掉:

self.setStyleSheet('QWidget { background-color: rgb(0, 0, 0) }'
#'QFrame { background-color: rgb(255, 255, 255) }'
#'QPushButton { background-color: rgb(0, 255, 0) }'
)
再次运行,frm,btn和主体窗都设置成了黑色:



3.4 最后将QWidget注掉,保留QFrame和QPushButton:

self.setStyleSheet(#'QWidget { background-color: rgb(0, 0, 0) }'
'QFrame { background-color: rgb(255, 255, 255) }'
'QPushButton { background-color: rgb(0, 255, 0) }'
)
再次运行,frm及btn分别设定为QFrame和QPushButton对应的白色和绿色:



根据3.1,self(Example类对象)与QWideget有类继承关系,但是与QFrame和QPushButton都没有类继承关系,而self中除主窗体设置成了QWidget对应的黑色,frm和btn也都分别成功设置成了QFrame和QPushButton对应的白、绿色,从而回答了步骤2中的疑问:frm和selector之间无须具备类继承关系也能使frm样式生效。
根据3.1-3.4,步骤2中关于“作用域”的猜测得到了证实。在3.3中,self对象中的QWidget对象(包含主体窗,frm和btn)的背景色都设置成了黑色;在3.2和3.1中,随着QFrame和QPushButton的放开,frm和btn也都具备了其各自的背景色,不再沿用其父类QWidget的黑色;而3.4中将QWidget注掉,“作用域”QFrame和QPushButton无法到达主体窗,因此主体窗未能设置背景色。

结论:对于通用样式设置函数

对象a.setStyleSheet('类A {样式1}'
'类B {样式2}'
'类C {样式3}')
可以理解为:以对象a为顶层窗体/组件,附着(注意:仅仅是“附着”,不涉及类继承关系)于对象a上的[b]所有类A对象的样式设置为样式1,所有类B对象的样式设置为样式2,所有类C对象的样式设置为样式3...[/b]

这里需要注意的是类A/类B/类C之间隐含的继承关系可能导致的样式覆盖的情形。那么,pyqt那么多类,怎么知道它们之间的继承关系呢?好东西就该拿出来分享,宝典来了,拿走不谢…

Qt5所有类(及其继承关系)官方参考:http://doc.qt.io/qt-5/hierarchy.html

[b]Qt5所有类(及其继承关系)中文参考:http://www.kuqin.com/qtdocument/qwidget.html[/b]

另外,Qt Style Sheets Examples:http://doc.qt.io/qt-5/stylesheet-examples.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: