对setStyleSheet的一点入门探索
2017-10-18 10:46
387 查看
最近学习pyqt教程(http://zetcode.com/gui/pyqt5/)到dialog章节时碰到一个疑问,先附上教程中的源码:
colordialog.py
我的疑问在initUI函数这里:
为了搞清楚这个问题,遂作以下尝试:
1. 将frm设置样式的类参数改为QFrame
2. 将frm设置样式的类参数改为QPushButton
于是猜测: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追加样式设定语句:
3.2 将对QPushButton对象设定样式的语句注释掉:
3.3 进一步将对QFrame对象设定样式的语句也注释掉:
3.4 最后将QWidget注掉,保留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/类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
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
相关文章推荐
- Qt利用setStyleSheet设置样式
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- QT5.2 + VS2012 给QWidget 对象使用setStyleSheet()设置背景图片运行不显示的问题
- pyqt setStyleSheet用法
- 关于QT stylesheet的使用的一点见解
- 继承 QWidget setStyleSheet无效,解决方法。
- setStyleSheet来设定窗口部件的样式(前景色,背景图片)
- setStyleSheet 设置多个属性
- Qt中各个控件利用Qt Designer来setStyleSheet
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- setStyleSheet来设定窗口部件的样式(前景色,背景图片)
- Qt中使用setStyleSheet对QPushButton按钮进行外观设置
- QT (QSS) 编程, QSS语法概述。。setstylesheet
- 自学QT之QWidget设置setstylesheet无效的问题
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- Qt—样式表(setStyleSheet())
- Qt中设置widget背景颜色/图片的注意事项(使用样式表 setStyleSheet())
- setStyleSheet来设定窗口部件的样式