PySide(PyQt)的小部件通过伪状态以及自定义特性改变外观

news2024/9/20 7:57:42

1、通过伪状态来改变外观

        伪状态是一种特殊的状态,通常用于描述控件在特定条件下的外观变化。这些状态不是控件的实际属性,而是用于在样式表中应用不同样式的标记。

        以QPushButton为例。在 PySide6 中,QPushButton 具有多种伪状态,每种伪状态可以通过样式表(QSS)来设定样式。以下是一些常见的伪状态及其对应的样式表设置方法:

正常状态(Normal):按钮处于未被点击、未被禁用的状态。

QPushButton {
    background-color: lightblue;
    color: black;
}

悬停状态(Hover):当鼠标悬停在按钮上时。

QPushButton:hover {
    background-color: lightgreen;
    color: black;
}

按下状态(Pressed):按钮被点击时。

QPushButton:pressed {
    background-color: red;
    color: white;
}

禁用状态(Disabled):按钮被禁用时。
获得焦点状态(Focus):按钮获得键盘焦点时。
活动状态(Active):按钮被激活时(通常用于不同的窗体或选项卡)。
checked:控件(单选按钮)被选中时。

demo:

from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout

app = QApplication([])

window = QWidget()
layout = QVBoxLayout()

button = QPushButton("Click Me")
button.setStyleSheet("""
    QPushButton {
    background-color: lightblue;
    color: black;
    }
    QPushButton:hover {
    background-color: lightgreen;
    color: black;
    }
    QPushButton:pressed {
        background-color: red;
        color: white;
    }
    QPushButton:disabled {
        background-color: gray;
        color: lightgray;
    }
    
""")

layout.addWidget(button)
window.setLayout(layout)
window.show()

app.exec()

 运行截图:

 

2、通过自定义特性来改变外观 

除了使用默认的伪特性,还可以自定义特性,通过改变自定义特性的方法改变外观。

from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout

app = QApplication([])


class Window(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUI()
        self.show()

    def setupUI(self):
        layout = QVBoxLayout()
        self.button_1 = QPushButton("Button_1")
        self.button_2 = QPushButton("Button_2")
        # 自定义的特性custom_attribute
        self.button_2.setProperty("custom_attribute", False)
        self.button_2.setStyleSheet("""
            QPushButton[custom_attribute="true"] {
            background-color: lightblue;
            color: red;
            }
        """)

        layout.addWidget(self.button_1)
        layout.addWidget(self.button_2)
        self.setLayout(layout)
        self.slot_signal()

    # 槽函数和信号连接
    def slot_signal(self):
        # 按钮1点击的槽函数
        def bt1_clicked():
            this = self.button_2
            this.setProperty("custom_attribute", not this.property("custom_attribute"))
            this.setStyleSheet(this.styleSheet())
        # 按钮1点击的连接
        self.button_1.clicked.connect(bt1_clicked)


window = Window()

app.exec()

示例代码中, 将按钮2设置了一个自定义特性custom_attribute,并且将其初始化为False:

self.button_2.setProperty("custom_attribute", False)

然后将按钮2的外观与自定义特性关联:

self.button_2.setStyleSheet("""
            QPushButton[custom_attribute="true"] {
            background-color: lightblue;
            color: red;
            }

 再将按钮2的自定义特性的改变与按钮1的点击连接:

# 按钮1点击的连接
        self.button_1.clicked.connect(bt1_clicked)

        def bt1_clicked():
            this = self.button_2
            this.setProperty("custom_attribute", not this.property("custom_attribute"))
            this.setStyleSheet(this.styleSheet())

 这样,每点击一次按钮1,按钮2的自定义特性就反转,并根据样式表改变外观。

需要注意的是,由于并没有给自定义特性的改变指定触发的事件,所以当自定义特性改变时,按钮并不能自动根据样式表改变外观,即使用update()和repaint()重绘都不行,在一些博主的demo中,使用update()和repaint()来改变外观,经过测试,并不能实现外观的改变,这个误导,耽误了我非常多的时间和精力。查阅了很多技术文档之后,正确的方法应该是*.setStyleSheet(*.styleSheet()),这样可以重新设置和应用样式表。另外,根据技术文档,在一些极端情况下,*.setStyleSheet(*.styleSheet())也有可能无效,可以采用下面这个语句组合来实现强制的样式表重新应用:

btn.style().unpolish(btn)
btn.style().polish(btn)
btn.update()

 使用polish方法的完整代码:

from PySide6.QtWidgets import QApplication, QPushButton, QWidget, QVBoxLayout

app = QApplication([])


class Window(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUI()
        self.show()

    def setupUI(self):
        layout = QVBoxLayout()
        self.button_1 = QPushButton("Button_1")
        self.button_2 = QPushButton("Button_2")
        # 自定义的特性custom_attribute
        self.button_2.setProperty("custom_attribute", False)
        self.button_2.setStyleSheet("""
            QPushButton[custom_attribute="true"] {
            background-color: lightblue;
            color: red;
            }
        """)

        layout.addWidget(self.button_1)
        layout.addWidget(self.button_2)
        self.setLayout(layout)
        self.slot_signal()

    # 槽函数和信号连接
    def slot_signal(self):
        # 按钮1点击的槽函数
        def bt1_clicked():
            this = self.button_2
            this.setProperty("custom_attribute", not this.property("custom_attribute"))
            this.style().unpolish(this)
            this.style().polish(this)
            this.update()
        # 按钮1点击的连接
        self.button_1.clicked.connect(bt1_clicked)


window = Window()

app.exec()

polish的更详细解释:PySide的style().unpolish()与style().unpolish()-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1947663.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

卷积神经网络(二)-AlexNet

前言: AlexNet是2012年ImageNet竞赛冠军(以领先第二名10%的准确率夺得冠军)获得者Hinton和他的学生Alex Krizhevsky设计的,在ILSVRC-2010测试集上取得了top-1错误率37.5%,top-5错误率17.0%(优于第二名的16.4%),明显优…

科技快讯丨智驱未来,校企共融:浪潮海岳携手山东大学软件学院开展低代码开发实训活动

近日,山东大学软件学院暑期实训活动圆满落幕。作为领先的企业数字化转型优秀服务商,浪潮海岳主导的低代码开发课题吸引了众多师生参训,取得了良好成效。 当前,低代码开发已成为软件行业降本增效、提升用户体验的必然选择&#xff…

labview实现两台电脑共享变量传输及同步

因为工作需要,需要实现多台主机间进行数据传输, 有两个备选方案, 1:建立tcp,然后自己解包 2:就是通过共享变量传输 虽然共享变量也是建立在TCP/IP上面的,但是不用自己解包呀 关于共享变量网络上…

vivo手机恢复出厂设置在哪里?清除数据后如何找回?2个技巧

随着使用时间的增长,手机可能会因为累积的缓存文件、不必要的数据或软件问题而出现性能下降或系统运行缓慢。为了解决这些问题,执行恢复出厂设置成为了一种流行的解决方案。那么,vivo手机恢复出厂设置在哪里?数据清除后该如何找回…

CCRC-DSO数据安全官:打造数据“冷链”,做强做大数据产业

在7月22日国新办举办的“推动高质量发展”系列新闻发布会上,国家数据局局长刘烈宏宣布,为响应党的二十届三中全会的决策,将加速推进数字经济发展机制的构建和完善数据要素市场制度。 他强调了对地方试点探索的支持,目标是建立强大…

基础复习(数组)

数组 一维数组 1.静态初始化 数据类型[] 数组名 new 数据类型[]{元素1,元素2,元素3,...}; 数据类型[] 数组名 {元素1,元素2,元素3...}; 2.动态初始化 数组存储的元素的数据类型[] 数组名字 new 数组存储的元素的数据类型[长度]; 3.执行原理 变量存储的是数组的地址值。…

Pyqt5新手教程

PyQt界面开发的两种方式:可视化UI 编程式UI (1)可视化UI:基于Qt Designer可视化编辑工具进行组件拖放、属性设置、布局管理等操作创建界面。 一是将其保存为.ui文件,然后在PyQt应用程序中加载和使用.ui文件。 二是使用…

接口自动化测试框架实战-3-文件读写封装

上一小节我们详细介绍了项目中所使用的接口文档,本小节我们将进入到接口测试框架第一个部分通用函数commons的开发,本小节我们重点完成文件读写方法的封装。 首先为什么要封装文件读写的方法,原因有如下几点: 读接口配置&#x…

B站音视频分开 大小问题

音频是33331 kb,视频是374661 kb 合并之后却是2561363 kb 这可能是B站音频和视频分开的原因吧

html实现酷炫美观的可视化大屏(十种风格示例,附源码)

文章目录 完整效果演示1.蓝色流线风的可视化大屏1.1 大屏效果1.2 大屏代码1.3 大屏下载 2.地图模块风的可视化大屏2.1 大屏效果2.2 大屏代码2.3 大屏下载 3.科技轮动风的可视化大屏3.1 大屏效果3.2 大屏代码3.3 大屏下载 4.蓝色海洋风的可视化大屏4.1 大屏效果4.2 大屏代码4.3 …

深入指南:VitePress 如何自定义样式

💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

边缘计算网关项目(含上报进程、32Modbus采集进程、设备搜索响应进程源码)

目录 边缘层 架构说明 包含知识点 数据上报进程 功能描述 功能开发 上报线程 数据存储线程 指令处理线程 项目源码 上报模块.c代码: 上报模块Makefile代码: STM32采集模块.c代码 设备搜索响应模块Linux部分.c代码 设备搜索响应模块Qt端代码.h …

计算机毕业设计-程序论文-高校智能排课系统

本系统开发采用技术为JSP、Bootstrap、Ajax、SSM、Java、Tomcat、Maven 此文章为本人亲自指导加编写,禁止任何人抄袭以及各类盈利性传播, 相关的代码部署论文ppt代码讲解答辩指导文件都有可私要 项目源码,请关注❥点赞收藏并私信博主&#xf…

UML通信图建模技术及应用例

新书速览|《UML 2.5基础、建模与设计实践》 在对系统的动态行为进行建模时,通信图常被用于按组织结构对控制流进行建模。与顺序图一样,一个单独的通信图只能显示一个控制流。 使用通信图建模时可以遵循如下策略: (1&#xff09…

操作系统杂项(九)

目录 一、简述sleep和wait的区别 1、sleep 2、wait 3、区别 二、简述线程池的设计思路,线程池中线程数量的决定因素 1、设计思路 2、线程池中线程数量 三、进程和线程相比,为何更慢 四、简述Linux零拷贝的原理 1、概念 2、优点 3、原理 五、…

MySQL第一阶段:多表查询、事务

继续我的MySQL之旅,继续上篇的DDL、DML、DQL、以及一些约束,该到了多表查询和事务的学习总结,以及相关的案例实现,为未来的复习以及深入的理解做好知识储备。 目录 多表查询 连接查询 内连接 外连接 子查询 事务 事务简介…

加油卡APP系统开发,线上发展优势分析

在当下社会中,汽车加油已经必不可少了,不管有什么出行计划,都需要提前给汽车加油或者中途加油。随着技术的发展,加油卡APP受到了有车一族的欢迎,大众可以在手机上给汽车加油,还能够享受诸多的优惠活动&…

python-阶乘和(赛氪OJ)

题目描述 求Sn​1!2!3!4!5!⋯n!的值,其中 𝑛n 是一个数字。输入格式: 输入一个整数 n。输出格式: 输出对应的 Sn​。 样例输入输出样例输入 5样例输出 153数据范围 对于 100% 的数据,保证1≤n≤20。来源/分类&#xff…

如何使用Python和Selenium解决reCAPTCHA

CAPTCHA已成为我们日常在线活动中重要的防御线。无论是登录账户、提交表单还是进行在线支付,CAPTCHA都在幕后保护我们的安全。然而,CAPTCHA有时可能会成为自动化的绊脚石,阻碍自动化测试、数据收集和效率提升。那么,如何以合法合理的方式绕过这些复杂的CAPTCHA挑战呢?在本文中…

导航不是GPS吗,有人用北斗吗?

在现代生活中,提到导航,人们脑海中最先浮现的往往是GPS。然而,近年来,中国自主研发的北斗导航系统(BeiDou Navigation Satellite System, BDS)正在迅速崛起,逐步占据全球导航市场的一席之地&…