Python GUI库PyQt5图形和特效样式QSS介绍


Posted in Python onFebruary 25, 2020

QSS介绍前言

QSS即Qt样式表,是用来自定义控件外观的一种机制,QSS大量参考了Css的内容,但QSS的功能要比Css弱得多,体现在选择器少,可以使用的QSS属性也少,而且并不是所有的属性都可以应用在PyQt的控件上,QSS使页面美化跟代码层分开,利于维护

QSS的语法规则

QSS的语法规则几乎与CSS相同,QSS样式由两部分组成,其中一部分是选择器(Selector),指定哪些软件会受到影响,另一部分是声明(Declaration),指定哪些属性应该在控件上进行设置,声明部分是一系列的“属性:值”对,使用(;)分割各个不同的属性值对,使用大括号({})将所有的声明包括在内,例如

QPushButton{color:red}

表示设置QPushButton类及其子类的所有实例的前景色是红色,其中,QPushButton表示选择器,指定所有的QPushButton类及其子类都会受到影响,注意,凡是继承自QPushButton的子类都会受到影响,这是与Css不同的地方,因为css应用的都是一些标签,没有类的结构,更没有子类的概念,{color:red}则是规则的定义,表示指定前景色是红色

实例:QSS语法规则示范

import sys
from PyQt5.QtWidgets import *

class WindowDemo(QWidget):
  def __init__(self):
    super(WindowDemo, self).__init__()
    #设置窗口标题
    self.setWindowTitle('QSS样式')

    #实例化按钮,设置显示文本
    btn1=QPushButton(self)
    btn1.setText('按钮1')

    # 实例化按钮,设置显示文本
    btn2=QPushButton(self)
    btn2.setProperty('name','btn2')
    btn2.setText('按钮2')

    #添加控件到布局中,设置窗口布局方式
    vbox=QVBoxLayout(self)
    vbox.addWidget(btn1)
    vbox.addWidget(btn2)

    #设置样式;按钮的背景颜色绿色
    # qssStyle = '''
    #  QPushButton[name='btn2']{background-color:green}
    #  '''
    qssStyle = '''
      QPushButton{background-color:green}
      '''
    #加载设置好的样式
    self.setStyleSheet(qssStyle)
if __name__ == '__main__':
  app=QApplication(sys.argv)
  win=WindowDemo()
  win.show()
  sys.exit(app.exec_())

运行效果如下

Python GUI库PyQt5图形和特效样式QSS介绍

代码分析

在这个例子中。整个窗口加载自定义的QSS样式,窗口中的按钮背景色都为绿色

首先定义了QSS样式,然后使用setStyleSheet()函数加载QSS样式,setStyleSheet()函数本身是QWidget的成员函数,PyQt中的大多数控件都是可以直接通过该函数来设置样式

qssStyle = '''QPushButton{background-color:green}'''#加载设置好的样式
self.setStyleSheet(qssStyle)

还可以使用多个选择器指定相应的声明,使用逗号将各个选择器分离,例如

QPushButton,QLineEdit,QComboBox {color:blue}

它相当于

QPushButton {color:blue}

QLineEdit {color:blue}

QComboBox {color:blue}

QSS选择器类型

QSS选择器有如下几种类型

类型 解析
通配选择器 *, 匹配所有的控件
类型选择器 QPushButton,匹配所有的QPushButton类及其子类的实例
属性选择器 QPushButton[name='mybtn'],匹配所有的name属性是myBtn的QPushButton实例。注意,该属性是可以自定义的,不一定非得是类本身具有的属性

示范;修改上面例子

给btn2设置属性名,代码如下

btn2.setProperty('name','btn2')

修改QSS样式表

#设置样式;按钮的背景颜色绿色

qssStyle = '''QPushButton[name='btn2']{background-color:green}'''

运行程序,效果如下

Python GUI库PyQt5图形和特效样式QSS介绍

类型 解析
类选择器 .QPushButton,匹配所有的QPushButton实例,但是不匹配子类,注意,前面有一个点,这是与css类选择器不同的地方
ID选择器 myButton,匹配所有的ID为myButton的控件,这里的id实际上就是objectName指定的值
后代选择器 QDialog QPushButton,匹配所有的QDialog容器中包含的QPushButton,不管是直接的,还是间接的
子选择器 QDialog>QPushButton,匹配所有的QDialog容器中包含的QPushButton,其中要求QPushButton的直接父类容器是QDialog

另外,上面所有的选择器可以联合使用,并且支持一次设置多种选择器类型,用逗号隔开,例如

#framecut,#frameInterrupt,#frameJoin {color:red}

表示这些ID使用的都是一个规则

#mytable QPushButton {color:red}

表示选择所有ID为mytable的容器中包含的QPushButton

方箱模型

在样式表中,每个部件都被看作是一个由四个同心相似的矩形组成的箱体:

空白(margin)、边框(border)、填充(padding)和内容(content)。

对于一个平面部件——例如一个空白、边框和填充都是0像素的部件——而言,这四个矩形是完全重合的。

空白区域位于边框外,并且总是透明的。

边框为部件提供了四周的框架,其border-style属性可以设置为一些内置的框架风格,如inset、outset、solid和ridge。

填充在边框和内容区域之间提供了空白间隔。

前景与背景

部件的前景色用于绘制上面的文本,可以通过color属性指定。

背景色用于绘制部件的填充矩形,可以通过background-color属性指定。

背景图片使用background-image属性定义,它用于绘制由background-origin指定的矩形区域(空白、边框、填充或内容)。

背景 图片在矩形区域内的对齐和平铺方式可以通过background-position和background-repeat属性指定。

如果指定的背景图片具有alpha通道(即有半透明效果),通过background-color指定的颜色将会透过透明区域。这一功能可以使背景图片在多种环境下重复利用。

该例子中使用的样式表如下所示:

QFrame {
  margin: 10px;
  border: 2px solid green;
  padding: 20px;
  background-color: gray;
  background-image: url(qt.png);
  background-position: top right;
  background-origin: content;
  background-repeat: none;
}

在这个例子中,QFrame四周的空白、边框和填充值都是一样的。

实际上margin属性可以在上下左右四个方向分别指定我们需要的不同值,例如:

QFrame {
  margin: 14px 18px 20px 18px;
}

同时,我们也可以分别指定margin-top、margin-right、margin-bottom、margin-left四个属性。

QFrame {
  margin-top: 14px;
  margin-right: 18px;
  margin-bottom: 20px;
  margin-left: 18px;
}

虽 然目前我们仅仅使用了QFrame作为例子,但是我们也可以同样的将这些属性应用于任何一个支持方箱模型的Qt部件,例如:QCheckBox、 QLabel、QLineEdit、QListView、QMenu、QPushButton、QTextEdit、和QToolTip。

创建可缩放样式

在默认情况下,通过background-image指定的背景图片会自动重复平铺,以覆盖部件的整个填充矩形(即边框里面的那个区域)。

如果我们想创建能够随着部件大小自动缩放而不是平铺的背景,我们需要设置一种称之为“边框图片”的东东。

“边框图片”可以通过border-image属性指定,它同时提供了部件的背景和边框。一个“边框图片”被分为九个部分(九宫格),有点向tic-tac-toe游戏的棋盘。

当一个部件的边框被填充时,四角的格子通常不会发生变化,而其余的五个格子则可能被拉伸或平铺以填充可用空间。

当指定一个“边框图片”时,除了图片本身,我们还必须指定用来分割九宫格的四条分割线。同时我们还必须指定非边角的格子是应该平铺还是拉伸,以及边框的宽度(用来确定边角格子的大小,防止边角被缩放变形)。

例如,下面的样式表定义了上图中的button:

QPushButton {
  border-width: 4px;
  border-image: url(button.png) 4 4 4 4 stretch stretch;
}

另外,“边框图片”还应该含有alpha通道,以使背景能够在边角处露出来。

控制大小

min-width和min-height两个属性可以用来指定一个部件的内容区域的最小大小。这两个值将影响部件的minimumSizeHint(),并在布局时被考虑。

例如:

QPushButton {
  min-width: 68px;
  min-height: 28px;
}

如果该属性没有被指定,最小大小将从部件的内容区域和当前样式中继承。

处理伪状态

部件的外观可以按照用户界面元素状态的不同来分别定义,这在样式表中被称为“伪状态”。例如,如果我们想在一个push button在被按下的时候具有sunken的外观,我们可以指定一个叫做 :pressed 的伪状态。

QPushButton {
  border: 2px outset green;
  background: gray;
}
QPushButton:pressed {
  border-style: inset;
}

可用的伪状态列表

伪状态 描述
checked button部件被选中
disabled 部件被禁用
enabled 部件被启用
focus 部件获得焦点
hover 鼠标位于部件上
indeterminate checkbox或radiobutton被部分选中
off 部件可以切换,且处于off状态
on 部件可以切换,且处于on状态
pressed 部件被鼠标按下
unchecked button部件未被选中

使用子部件定义微观样式

许多部件都包含有子元素,这些元素可以称为“子部件”。Spin box的上下箭头就是子部件最好的例子。

子 部件可以通过::来指定,例如QDateTimeEdit::up-button。定义子部件的样式与定义部件非常相似,它们遵循前面提到的方箱模型(即 它们可以拥有自己的边框、背景等),并且也可以和伪状态联合使用(例如QSpinBox::up-button:hover)。

可用的子部件类型

子部件列表

子部件 描述
::down-arrow combo box或spin box的下拉箭头
::down-button spin box的向下按钮
::drop-down combo box的下拉箭头
::indicator checkbox、radio button或可选择group box的指示器
::item menu、menu bar或status bar的子项目
::menu-indicator push button的菜单指示器
::title group box的标题
::up-arrow spin box的向上箭头
::up-button spin box的向上按钮

通过指定subcontrol-position和subcontrol-origin属性,子部件可以被放置在部件箱体内的任何位置。并且,子部件的位置 还可以使用相对或绝对的方式进一步的调整。具体选择何种调整方式取决于子部件具有固定的大小,还是会随着父部件而变化。

相对定位

相对定位适合于子部件具有固定大小的情形(通过width和height指定子部件大小)。使用这种方式,子部件可以以相对于subcontrol- position和 subcontrol-origin属性定义的原始位置进行移动调整。

使用left属性可以把子部件向右移,top属性可以把子部件向左移。

例如:

QPushButton::menu-indicator {
  image: url(menu_indicator.png);
  width: 13px;
  height: 13px;
  subcontrol-origin: padding;
  subcontrol-position: bottom right;
}

当按下按钮时,我们可以把菜单指示器从原来的位置向右下方移动几个像素来模拟按钮按下的状态。

QPushButton::menu-indicator:pressed {
  position: relative;
  top: 2px;
  left: 2px;
}

绝对定位

绝对定位适合于子部件的位置随父部件的变化而变的情形。与前面的例子相同,subcontrol-origin定义了父部件箱体的参考矩形。子部件的矩形区域则可以随后通过相对于这个参考矩形四边的偏移量来定义。

QPushButton::menu-indicator {
  border: 2px solid red;
  subcontrol-origin: padding;
  position: absolute;
  top: 2px;
  right: 2px;
  bottom: 2px;
  left: 40px;
}

对于宽度或高度固定的子部件,subcontrol-position被用来说明其在subcontrol-origin指定矩形内的对其方式:

QPushButton::menu-indicator {
  image: url(menu_indicator.png);
  width: 13px;
  subcontrol-origin: padding;
  subcontrol-position: bottom right;
  position: absolute;
  top: 2px;
  bottom: 2px;
  right: 2px;

本文先简单介绍下PyQt5的样式QSS,更多关于Python GUI库PyQt5图形和特效样式QSS请查看下面的相关链接

Python 相关文章推荐
学习python (2)
Oct 31 Python
python通过urllib2获取带有中文参数url内容的方法
Mar 13 Python
Python+django实现文件上传
Jan 17 Python
基于python中theano库的线性回归
Aug 31 Python
实时获取Python的print输出流方法
Jan 07 Python
Python基于matplotlib画箱体图检验异常值操作示例【附xls数据文件下载】
Jan 07 Python
基于python实现蓝牙通信代码实例
Nov 19 Python
Python获取、格式化当前时间日期的方法
Feb 10 Python
推荐8款常用的Python GUI图形界面开发框架
Feb 23 Python
Python命名空间及作用域原理实例解析
Aug 12 Python
20行Python代码实现一款永久免费PDF编辑工具的实现
Aug 27 Python
Python如何实现机器人聊天
Sep 10 Python
python 伯努利分布详解
Feb 25 #Python
Python3如何在Windows和Linux上打包
Feb 25 #Python
python实现可下载音乐的音乐播放器
Feb 25 #Python
Python实现分数序列求和
Feb 25 #Python
python等差数列求和公式前 100 项的和实例
Feb 25 #Python
Django单元测试中Fixtures用法详解
Feb 25 #Python
python实现音乐播放器 python实现花框音乐盒子
Feb 25 #Python
You might like
粗略计算在线时间,bug:ip相同
2006/12/09 PHP
PHP二维数组矩形转置实例
2016/07/20 PHP
TP5多入口设置实例讲解
2020/12/15 PHP
js中for in的用法示例解析
2013/12/25 Javascript
js中top的作用深入剖析
2014/03/04 Javascript
IE中JS跳转丢失referrer问题的2个解决方法
2014/07/18 Javascript
使用node+vue.js实现SPA应用
2016/01/28 Javascript
基于vue实现多引擎搜索及关键字提示
2017/03/16 Javascript
jQuery选择器_动力节点Java学院整理
2017/07/05 jQuery
基于JavaScript实现微信抢红包功能
2017/07/20 Javascript
JavaScript事件委托原理与用法实例分析
2018/06/07 Javascript
jQuery实现获取选中复选框的值实例详解
2018/06/28 jQuery
在Vuex使用dispatch和commit来调用mutations的区别详解
2018/09/18 Javascript
在js代码拼接dom对象到页面上的模板总结
2018/10/21 Javascript
解决vue-cli webpack打包开启Gzip 报错问题
2019/07/24 Javascript
turn.js异步加载实现翻书效果
2019/07/25 Javascript
Node.js操作MongoDB数据库实例分析
2020/01/19 Javascript
[48:35]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 TNC vs Optic
2018/04/03 DOTA
python抓取豆瓣图片并自动保存示例学习
2014/01/10 Python
Python统计列表中的重复项出现的次数的方法
2014/08/18 Python
python监控文件或目录变化
2016/06/07 Python
浅谈python抛出异常、自定义异常, 传递异常
2016/06/20 Python
Django 使用Ajax进行前后台交互的示例讲解
2018/05/28 Python
Python实现的服务器示例小结【单进程、多进程、多线程、非阻塞式】
2019/05/23 Python
python批量读取文件名并写入txt文件中
2020/09/05 Python
python绘制规则网络图形实例
2019/12/09 Python
python利用proxybroker构建爬虫免费IP代理池的实现
2021/02/21 Python
HTMl5的存储方式sessionStorage和localStorage详解
2014/03/18 HTML / CSS
美国高端医师级美容产品电商:BeautifiedYou.com
2017/04/17 全球购物
Vans澳大利亚官网:购买鞋子、服装及配件
2019/09/05 全球购物
入团者的自我评价分享
2013/12/02 职场文书
公司新员工的演讲稿注意事项
2014/01/01 职场文书
网站文案策划岗位职责
2015/04/14 职场文书
家长会后的感想
2015/08/11 职场文书
5种方法告诉你如何使JavaScript 代码库更干净
2021/09/15 Javascript
Vscode中SSH插件如何远程连接Linux
2022/05/02 Servers