PyQt5 定制个性化软件界面

1、功能概述
Qt样式表(Qt Style Sheets,QSS)是用于定制用户界面的强有力的机制,其概念、术语是受到HTML中的级联样式表(Cascading Style Sheets,CSS)启发而来的。

与HTML的CSS类似,Qt的样式表是用纯文本的格式定义的,在应用程序运行时可以载入和解析这些样式定义。使用样式表可以定义各种界面组件(QWidget类及其子类)的样式,从而使应用程序的界面呈现不同的效果。很多软件具有选择不同界面主题的功能,使用Qt的样式表就可以实现这样的功能。

在UI Designer中就集成了Qt样式表的编辑功能。在设计窗体界面时,选择窗体或某个界面组件,单击鼠标右键,在弹出的快捷菜单中选择“Change styleSheet…”菜单项就可以出现样式表编辑对话框。

QWidget{
     background-color: rgb(0, 85, 127);
     font: 12pt "宋体";
}

这定义了QWidget类的背景颜色、字体大小和名称。这个样式定义会应用于QWidget类及其子类:

QLineEdit{
     border: 2px groove gray;
     border-radius: 10px;
     padding: 2px 4px;
     color: rgb(255, 255, 0);
     border-color: rgb(0, 255, 0);
}

以上定义了QLineEdit类的显示效果,包括边框宽度、圆角边框的半径、边框颜色、文字颜色等。

PyQt5 定制个性化软件界面_第1张图片
下拉菜单的按钮,可以定义一些常用的样式属性,例如前景色color、背景色background-color、选中后颜色selection-color、背景图片background-image等。

在窗体可视化设计时设置样式表后立刻就可以显示效果。

Qt样式表句法:Qt样式表的句法(Syntax)与HTML的CSS句法几乎完全相同。Qt样式表包含一系列的样式法则,一个样式法则由一个选择器(selector)和一些声明(declaration)组成。

QPlainTextEdit{
     font: 12pt "仿宋";
     color: rgb(255, 255, 0);
     background-color: rgb(0, 0, 0);
}

QPlainTextEdit就是选择器,表明后面花括号里的样式声明应用于QPlainTextEdit类及其子类。样式声明部分是样式法则列表,每个样式法则由属性和值组成,每条法则用分号结束。每条样式法则由“属性:值”构成。
font属性、字体大小为12pt、字体名称为“仿宋”,当一个属性有多个值时,多个值之间用空格隔开。

Qt样式表支持CSS2中定义的所有选择器

选择器 例子 用途
通用选择器 * 所有组件
类型选择器 QPushButton 所有QPushButton类及其子类的组件
属性选择器 QPushButton[flat = false] 所有flat属性为false的QPushButton类及其子类的组件。如果样式表应用后组件的属性再发生变化,需要重新应用样式表才能刷新显示效果
非子类选择器 .QPushButton 所有QPushButton类的组件,但是不包括QPushButton的子类
ID选择器 QPushButton # btnOK objectName为btnOK的QPushButton实例
从属对象选择器 QDialog QPushButton 所有从属于QDialog的QPushButton类的实例,即QDialog对话框里的所有QPushButton
子对象选择器 QDialog > QPushButton 所有直接从属于QDialog的QPushButton类的实例

选择器可以组合使用,一个样式声明可以应用于多个选择器。

QPlainTextEdit,QLineEdit,QPushButton,QCheckBox{
     color: rgb(255, 255, 0);
     background-color: rgb(0, 0, 0);
}

注意:QSS的句法和其中的符号标记与Python语言无关,所以在QSS中表示bool值的常量是true和false,不要用Python中首字母大写的True和False。

子控件:比如QComboBox的下拉按钮,QSpinBox的上、下按钮。通过选择器的子控件可以对这些界面元素进行显示效果控制。

QComboBox::drop-down{ image: url(:/images/images/down.bmp); }

选择器QComboBox::drop-down选择了QComboBox的drop-down子控件,定义的样式是设置其image属性为资源文件中的图片down.bmp。

关于Qt的子控件列表,详见Qt的帮助文档。

伪状态:选择器可以包含伪状态,使得样式法则只能应用于界面组件的某个状态,也就是一种条件应用法则。伪状态出现在选择器的后面,用一个冒号隔开。

QLineEdit:hover{ background-color: lime;
                    color: yellow;}

定义了当鼠标移动到QLineEdit上方时(hover),改变QLineEdit的背景色和前景色。

对伪状态取反,方法是在伪状态前面加一个感叹号。

QLineEdit:!read-only{ background-color: rgb(235, 255, 251); }

定义了readonly属性为false的QLineEdit的背景色。

伪状态可以串联使用,相当于逻辑与的计算

QCheckBox:hover:checked{ color: red; }

定义了当鼠标移动到一个被勾选了的QCheckBox组件上方时,其字体颜色变为红色。意思是如果只是鼠标移动到QCheckBox上,或者QCheckBox只是处于勾选时,字体不会变红。

伪状态可以并联使用,相当于逻辑或的计算

QCheckBox:hover, QCheckBox:checked{ color: red; }

鼠标移动到QCheckBox组件上方或QCheckBox组件被勾选时,字体颜色变为红色。其中一项成立即变红。

子控件也可以使用伪状态

QCheckBox::indicator:checked{
          image: url(:/images/images/checked.bmp);}
QCheckBox::indicator:unchecked{
          image: url(:/images/images/unchecked.bmp);}

定义了QCheckBox的indicator在checked和unchecked两种状态下的显示图片,例如,可以得到图示的效果。
在这里插入图片描述
Qt样式定义中常见的一些伪状态,熟悉这些伪状态并灵活应用可以定义自己想要的界面效果。

属性:Qt样式表内对每一个选择器可定义多条样式规则,每条规则是一个“属性:值”对,Qt样式表中可定义的属性很多,可以在Qt的帮助文件中查找“Qt Style Sheets Reference”查看所有属性的详细说明。

PyQt5 定制个性化软件界面_第2张图片
在“编辑样式表”对话框中,可以选择“添加资源”、“添加渐变”、"添加颜色"和“添加字体”。
✔添加资源:从项目的资源文件中选择图片。
✔添加颜色:用于设置组件的各种颜色。
✔添加渐变:用于设置组件的各种渐变色。

每个界面组件都可以用下图进行表示。
PyQt5 定制个性化软件界面_第3张图片
(1)content是显示内容矩形区域,例如QLineEdit用于显示文字的区域。max-width、min-width、max-height、min-height属性分别定义最大/最小宽度和高度就是定义这个矩形区,例如:

QLineEdit{
     min-width:50px;
     max-height:40px;
}

(2)padding是包围content的矩形区域,通过padding属性可以定义padding的宽度,或padding-top、padding-bottom、padding-left、padding-right分别定义padding的上、下、左、右宽度,例如:

QLineEdit{ padding: 0px 10px 0px 10px;}

(3)border是包围padding的边框,通过border属性(或border-width、border-style、border-color)可以定义边框的线宽、线型和颜色,也可以分别定义border的上、下、左、右的线宽和颜色。使用border-radius可以定义边框转角的圆弧半径,从而构造具有圆角矩形的编辑框或按钮等组件,例如:

QLineEdit{
     border-width: 2px;
     border-style: solid;
     border-color: gray;
     border-radius: 10px;
     padding: 0px 10px; 
}

(4)margin是border之外与父组件之间的空白边距,可以分别定义上、下、左、右的边距大小。

Qt样式表的使用
1.程序中使用Qt样式表
第一种:是在可视化设计UI窗体时,直接用样式表编辑器为窗体或窗体上的组件设计样式表,这样设计的样式保存在窗体的.ui文件里,窗体创建时会自动应用所设计的样式表。

第二种是使用QApplication类的setStyleSheet()函数在应用程序创建时,为应用程序全局设置样式。

if  __name__ == "__main__":        #用于当前窗体测试
   app = QApplication(sys.argv)    #创建GUI应用程序
   app.setStyleSheet("QLineEdit { background-color: gray }")
   form=QmyWidget()      #创建窗体
   form.show()
   sys.exit(app.exec_())

这里为应用程序里所有的QLineEdit组件设置样式,如果应用程序内的QLineEdit组件没有再被设置其他样式,则所有QLineEdit组件的背景色为灰色。

也可以使用QWidget的setStyleSheet()函数为一个窗口、一个对话框或一个界面组件设置样式,一般在窗体的构造函数里设置。

class QmyWidget(QWidget): 
   def __init__(self, parent=None):
       super().__init__(parent) 
      self.ui=Ui_Widget()    
      self.ui.setupUi(self)  
      self.setStyleSheet("QLineEdit { background-color: red }")

这样为本窗体上的所有QLineEdit组件设置样式,即背景色为红色。

还可以用某个具体组件调用setStyleSheet()函数,因为界面组件都是QWidget的子类。

self.ui.editName.setStyleSheet("color: blue;"
                     "background-color: lime;"
                     "selection-color: yellow;"
                     "selection-background-color: red;")

这是设置一个objectName为editName的组件的样式,注意这时在样式表中无须设置selector名称,所设置的样式只应用于editName这个组件。

这样将样式表固定在程序中,很显然是无法实现界面效果切换的。为了动态切换界面效果,一般将样式表定义保存为.qss后缀的纯文本文件,然后在程序中打开文件,读取文本内容,再调用setStyleSheet()函数应用样式。

if  __name__ == "__main__":        #用于当前窗体测试
   app = QApplication(sys.argv)    #创建GUI应用程序
   file = QFile("myStyle.qss")
   file.open(QFile.ReadOnly)
   qtBytes = file.readAll()     #QByteArray
   pyBytes = qtBytes.data()     #QByteArray转换为bytes
   styleStr = pyBytes.decode("utf-8")    #bytes转换为str
   app.setStyleSheet(styleStr)

   form = QmyWidget()    #创建窗体
   form.show()
   sys.exit(app.exec_())

这里使用了同目录下的文件myStyle.qss,这个文件里存储了所有的样式定义。使用样式文件的好处是,如果要改变界面效果,只需修改文件或切换文件即可,如同多语言界面的处理方式一样,也便于使用第三方的样式定义文件,实现专业的界面效果。

2.样式定义的明确性
当多条样式法则对一个属性定义了不同值时,就会出现冲突。例如:

QPushButton#btnSave { color: gray }
QPushButton { color: red }

在上面的例子中,QPushButton#btnSave被认为是比QPushButton更明确的选择器,因为它指向一个具体对象,而不是QPushButton的所有实例。所以,如果是在一个窗口上应用上面的两条法则,则btnSave按钮的前景色为gray,而其他按钮的前景色为red。

同样,具有伪状态的选择器被认为比没有伪状态的选择器明确性更强,例如:

QPushButton:hover { color: white }
QPushButton { color: red }

这样,当鼠标在按钮上停留时颜色为white,否则颜色为red。

如果两个选择器具有相同的明确性,则以法则出现的先后顺序为准,后出现的法则起作用,例如:

QPushButton:hover { color: white }
QPushButton:enabled { color: red }

这里的两个选择器具有相同的明确性,所以,当鼠标停留在一个使能的按钮上时,只有第二条法则起作用。这种情况下,如果不希望出现冲突,应该修改法则以使其更明确,如下面这两条法则是不冲突的:

QPushButton:hover:enabled { color: white }
QPushButton:enabled { color: red }

父子关系的两个类作为选择器时,具有相同的明确性,例如:

QPushButton { color: red }
QAbstractButton { color: gray }

这两个选择器的明确性相同,所以只依赖于语句的先后顺序。

3.样式定义的级联性
样式定义可以在应用程序、窗体或一个具体组件中定义,任何一个组件的样式是其父组件、父窗体和应用程序的样式的融合。当出现冲突时,组件会使用离自己最近的样式定义,即按顺序使用组件自己的样式、父组件的样式定义、父窗体的样式定义或应用程序的样式定义,而不考虑样式选择器的确定性。
例如,在QApplication中设置全局样式:

from PyQt5.QtWidgets import  qApp
qApp.setStyleSheet("QPushButton { color: red }")

那么应用程序中所有未再定义样式的QPushButton的前景颜色为red。qApp是表示当前应用程序的全局变量,需要从PyQt5.QtWidgets模块导入。

如果在一个窗体类(如QmyWidget)中再定义样式:

self.setStyleSheet("QPushButton { color: blue }")

则窗体上的按钮的前景色为blue,而不是red。

如果窗体上有一个名称为btnSave的QPushButton按钮,其样式定义如下:

self.ui.btnSave.setStyleSheet(
            "color: yellow; background-color: black;")

按钮btnSave按照自己的样式显示前景和背景色。

Qt样式表功能强大,可以设计出独具特色的界面效果,但是这需要有较好的美工设计,而涉及编程的内容并不太多。

你可能感兴趣的:(PyQt,GUI,笔记,qt,开发语言,python)