基于深度学习的视觉检测小项目(十一) 动态样式表的实践

news2025/1/13 18:48:03

动态样式表的基础知识:PySide6,定义动态的样式表-CSDN博客

pyside6的小部件种类、功能和从属关系基础知识:PySide6的常用小部件汇总-CSDN博客

        动态样式表的设计思路是使用了类似占位符的概念,设置项和颜色值都用代称,通过改变代称映射的实际值,就可以动态和灵活地改变样式表,这一点,与编程中的变量概念也很相似,暂且称之为伪变量。我看过非常多的pyside的demo,并没有见到过类似的先例,所以一切都是在黑暗中摸索和实践,也许有比我更好的方法,期待高人的指正。

首先通过一个例子说明一下动态样式表的设计思路:

在这里,有两个JSON文件,文件映射了设置名和颜色名的值。内容分别如下:

• 颜色值的映射:

{
  "colors": {
    "红色": "#dc1e1e",
    "浅红": "#ee8f8f",
    "深红": "#6e0f0f",
    "绿色": "#1edc1e",
    "浅绿": "#8fee8f",
    "深绿": "#0f6e0f",
    "蓝色": "#1e1edc",
    "浅蓝": "#8f8fee",
    "深蓝": "#0f0f6e"
}

• 设置值的映射:

{
    "color_setting": {
        "基底色": "深蓝",
        "窗口色": "浅绿",
        "顶部标签色": "黑色",
        "按钮底色": "浅蓝",
        "常规文字色": "深红"
    }
}

然后将样式表定义在文件中,样式表文件的内容demo:

/*########项目级的的样式表都在此设置#######*/
/*##########默认的父类颜色###############*/
QWidget{   /*类型选择器*/
    background-color: 基底色;
    color: 常规文字色
}
.QFrame{   /*类选择器*/
    background-color: 窗口色;
    color: 常规文字色;
}

/*#########按钮的通用默认设置################*/
/*按钮的默认背景色*/
QPushButton {
    background-color: 按钮底色;
}
/*#########顶部标签区颜色设置############*/
/*顶部标签区颜色*/
#form_top {    /*名称选择器*/
    background-color: 顶部标签色;
}
/*顶部标签区的标签文字颜色*/
#form_top QLabel{
    background-color: 基底色;
    color: 文字颜色;
}

        这样的样式表文件,有一个是项目级别的总设置,在总设置里,根据继承关系从父到子逐层设计大类和通用的特性,在总设置里基本就可以涵盖大部分的部件的显示特性。如果有需要,每个窗口可以有自己的附加样式表文件,通过局部的本地设置来实现差异化。通过灵活运用类选择器、类型选择器、以及合适的后代选择器,就可以实现样式表的全局统一设置和本地化的个性设置。

        这次把项目的目录结构做了一个修改,尝试在ui界面的目录中,以画面为单位作为分目录,这样更方便管理,当然了每个人可以根据自己的偏好和能力自己搞结构。

新的目录结构如下图:

项目
├── AI_proj/   # AI相关
│   ├── AI_proj说明.md
│   ├── media/  # AI有关的图像等媒体文件
│   │   ├── mark/
│   │   ├── predict/
│   │   └── source/
│   └── models/
├── DB_proj/    # 数据库相关
│   └── DB_proj说明.md
├── UI_proj/     # 显示界面相关
│   ├── UI_proj说明.md   
│   ├── functions/   # 功能函数
│   │   ├── form_center.py   # 显示居中
│   │   └── get_style_sheet.py   # 获取样式表
│   ├── settings/    #  设置项
│   │   ├── color_card.json   # 色卡文件
│   │   ├── color_setting.json    # 颜色设置文件
│   │   └── style_uiproj.qss      # 项目级的样式表文件
│   ├── ui_forms/       # 所有的显示界面文件相关
│   │   ├── __init__.py    # 这里设置项目所有界面文件列表,如果新增或删除了画面,需修改这里
│   │   ├── main_window/   # 主窗口相关的各种文件,如果增减画面,增减这样的目录即可
│   │   ├── settings/     # 设置
│   │   └── start_up/    #  起始界面相关的各种文件,如果增减画面,增减这样的目录即可
│   │       ├── start_up.py   # 由uic工具从ui文件转换而来的py文件
│   │       ├── start_up.ui   # 在designer中组态的ui格式的界面文件
│   │       ├── start_up_func.py   # 界面文件的后端脚本
│   │       └── style_start_up.qss   # 本界面的补充样式表文件
│   └── ui_project.py    # 生成项目文件的脚本
├── main.py    # 主程序
├── print_this.py    # 打印目录树的脚本
├── settings/         # 设置
└── tmp/     # 临时文件和垃圾文件

修改后的部分代码如下:

main.py:

import sys
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication
from UI_proj.ui_forms import *  # 导入所有窗口的后端脚本
from UI_proj.ui_project import uiproj   # 导入项目,uiproj是在ui_project.py中实例化的全局的ui项目类


def main():
    app = QApplication(sys.argv)

    def run():
        uiproj.forms = []  # 项目的所有窗口列表
        uiproj.timer.start(1000)  # 启动全局定时器
        # 添加窗口
        def add_forms():            
            # #################添加起始画面####################
            form_start_up = start_up_func.FormStart_up()  # 实例化窗口类
            form_start_up.setWindowFlag(Qt.FramelessWindowHint)  # 设置窗口无边框
            form_start_up.show()  # 显示窗口
            uiproj.forms.append(form_start_up)  # 添加到窗口列表

        add_forms()

    run()

    sys.exit(app.exec())

if __name__ == "__main__":
    main()

色卡文件,color_card.json:

{
  "colors": {
    "红色": "#dc1e1e",
    "浅红": "#ee8f8f",
    "深红": "#6e0f0f",
    "绿色": "#1edc1e",
    "浅绿": "#8fee8f",
    "深色": "#0f6e0f",
    "蓝色": "#1e1edc",
    "浅蓝": "#8f8fee",
    "深蓝": "#0f0f6e",
    "黄色": "#dcdc00",
    "浅黄": "#eeee80",
    "深黄": "#6e6e00",
    "橙色": "#cc8400",
    "浅橙": "#e6c280",
    "深橙": "#664200",
    "灰色": "#a0a0a0",
    "浅灰": "#eeeeee",
    "深灰": "#434343",
    "白色": "#ffffff",
    "黑色": "#000000"
  }
}


        在色卡文件中定义了标称的颜色对应的颜色值,可以在任何时候从文件中修改这个值,而无需找到应用它的地方去一一修改。 

颜色设置文件,color_setting.json:

{
    "color_setting": {
        "基底色": "黑色",
        "窗口色": "深灰",
        "顶部标签色": "黑色",
        "按钮底色": "浅蓝",
        "常规文字色": "浅灰"
    }
}

这里定义了一些泛指的基本颜色,通过修改这个文件,就可以整体修改界面的显示风格。

项目级的样式表文件,style_uiproj.qss:

/*########项目级的的样式表都在此设置#######*/


/*##########默认的父类颜色###############*/
QWidget{
    background-color: 基底色;
    color: 常规文字色;
}
QFrame{
    background-color: 窗口色;
    color: 常规文字色;
}

/*#########按钮的默认设置################*/
/*按钮的默认背景色*/
QPushButton {
    background-color: 按钮底色;
}
/*#########顶部标签区颜色设置############*/
/*顶部标签区颜色*/
#form_top {
    background-color: 顶部标签色;
}
/*顶部标签区的标签文字颜色*/
#form_top QLabel{
    background-color: 基底色;
    color: 常规文字色;
}


这个文件定义了项目全局的通用特性。

画面start_up的本地级别的样式表文件,style_start_up.qss:

/*########start_up(起始画面)的本地样式表在此设置#######*/

/*#########按钮的默认设置################*/
/*按钮的文字颜色*/
QPushButton {
    color: 深红;
}
#btn_quit {
    background-color: 深红;
    color: 黑色;
}

        可以看到,在本地级的样式表文件中,对按钮的显示做了补充和覆盖的设置。

 画面start_up的后端脚本,start_up_func.py:

# start_up画面(起始画面的后端功能函数)
from PySide6.QtCore import Slot, Qt
from PySide6.QtWidgets import QWidget, QApplication

from . import start_up   # 导入使用uis工具从start_up.ui生成而来的start_up.py文件
from UI_proj.ui_project import uiproj     # 导入全局的ui项目对象
from UI_proj.functions.get_style_sheet import get_style_sheet
# from . import styles_rc


# 定义窗口类
class FormStart_up(QWidget, start_up.Ui_form_base):
    def __init__(self):
        super().__init__()
        self.color_base = ""
        self.setupUi(self)   # 加载窗口
        self.run()   # 初始化运行窗口

    def run(self):   # 窗口的运行函数
        self.show()  # 显示窗口
        style_sheet = get_style_sheet('settings/color_card.json', 'settings/color_setting.json', 'settings/style_uiproj.qss')  # 获取项目级别的样式表
        style_sheet += get_style_sheet('settings/color_card.json', 'settings/color_setting.json', 'ui_forms/start_up/style_start_up.qss')  # 获取本画面的本地样式表并与项目级别样式表合并
        print(style_sheet)

        self.setStyleSheet(style_sheet)  # 设置窗口样式

        # 设置窗口居中
        def center():
            screen = QApplication.primaryScreen().geometry()
            size = self.geometry()
            self.move(
                (screen.width() - size.width()) // 2,
                (screen.height() - size.height()) // 2
            )
        center()  # 设置窗口居中
       

还有一些小的脚本未列出代码。感兴趣的同学可以下载本文绑定的资源。

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

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

相关文章

Spring Boot 支持哪些日志框架

Spring Boot 支持多种日志框架,主要包括以下几种: SLF4J (Simple Logging Facade for Java) Logback(默认)Log4j 2Java Util Logging (JUL) 其中,Spring Boot 默认使用 SLF4J 和 Logback 作为日志框架。如果你需要使…

快速导入请求到postman

1.确定请求,右键复制为cURL(bash) 2.postman菜单栏Import-Raw text,粘贴复制的内容保存,请求添加成功

Golang的网络流量分配策略

## 1. Golang中的网络流量分配策略 简介 在Golang中,网络流量分配策略是指如何有效地管理和优化网络请求的分配,以提高系统的性能和稳定性。优秀的网络流量分配策略能够使系统更好地应对高并发和大流量的情况,同时有效地避免网络拥堵和性能瓶…

【硬件介绍】Type-C接口详解

一、Type-C接口概述 Type-C接口特点:以其独特的扁头设计和无需区分正反两面的便捷性而广受欢迎。这种设计大大提高了用户的使用体验,避免了传统USB接口需要多次尝试才能正确插入的问题。Type-C接口内部结构:内部上下两排引脚的设计虽然可能不…

二、BIO、NIO编程与直接内存、零拷贝

一、网络通信 1、什么是socket? Socket 是应用层与 TCP/IP 协议族通信的中间软件抽象层,它是一组接口,一般由操作 系统提供。客户端连接上一个服务端,就会在客户端中产生一个 socket 接口实例,服务端每接受 一个客户端…

Android车机DIY开发之软件篇(九)默认应用和服务修改

Android车机DIY开发之软件篇(九)默认应用和服务修改 默认应用位置 ~/packages/apps/Car 增加APP 1.增加 XXXX.app 和Android.mk 2. 修改~/build/make/target/product/handheld_system_ext.mk 默认服务位置 ~/frameworks/base/services/java/com/android/server 查看服务列…

【Rust】错误处理机制

目录 思维导图 引言 一、错误处理的重要性 1.1 软件中的错误普遍存在 1.2 编译时错误处理要求 二、错误的分类 2.1 可恢复错误(Recoverable Errors) 2.2 不可恢复错误(Unrecoverable Errors) 三、Rust 的错误处理机制 3…

DDD - 微服务设计与领域驱动设计实战(上)_统一建模语言及事件风暴会议

文章目录 Pre概述业务流程需求分析的困境统一语言建模事件风暴会议什么是事件风暴(Event Storming)事件风暴会议 总结 Pre DDD - 软件退化原因及案例分析 DDD - 如何运用 DDD 进行软件设计 DDD - 如何运用 DDD 进行数据库设计 DDD - 服务、实体与值对…

用HTML + CSS实现太极图

目录 一、效果图 二、实现思路 三、完整代码 四、总结 一、效果图 如图所示,太极图一半为黑色(代表阴),另一半为白色(代表阳)。这两部分相互环绕,形成一种流动的、旋转的感觉。 二、实现思…

Apache Hadoop YARN框架概述

一、YARN产生和发展简史 1.1背景 数据、程序、运算资源(内存、CPU)三者组在一起,才能完成数据的计算处理过程。在单机环境下,三者之间协调配合不是太大问题。为了应对海量数据的处理场景,Hadoop软件出现并提供了分布…

一个个顺序挨着来 - 责任链模式(Chain of Responsibility Pattern)

责任链模式(Chain of Responsibility Pattern) 责任链模式(Chain of Responsibility Pattern)责任链模式(Chain of Responsibility Pattern)概述责任链结构图责任链模式概述责任链模式涉及的角色 talk is c…

.NET framework、Core和Standard都是什么?

对于这些概念一直没有深入去理解,以至于经过.net这几年的发展进化,概念越来越多,越来越梳理不容易理解了。内心深处存在思想上的懒惰,以为自己专注于Unity开发就好,这些并不属于核心范畴,所以对这些概念总是…

【Java回顾】Day5 并发基础|并发关键字|JUC全局观|JUC原子类

JUC全称java.util.concurrent 处理并发的工具包(线程管理、同步、协调) 一.并发基础 多线程要解决什么问题?本质是什么? CPU、内存、I/O的速度是有极大差异的,为了合理利用CPU的高性能,平衡三者的速度差异,解决办法…

android framework.jar 在应用中使用

在开发APP中&#xff0c;有时会使用系统提供的framework.jar 来替代 android.jar, 在gradle中配置如下&#xff1a; 放置framework.jar 依赖配置 3 优先级配置 gradle.projectsEvaluated {tasks.withType(JavaCompile) {Set<File> fileSet options.bootstrapClasspat…

CHAIN OF RESPONSIBILITY(职责链)—对象行为型模式

1. 意图 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 2. 动机 考虑一个图形用户界面中的上下文有关的帮助机制。用户在界面的任一部分…

Java高频面试之SE-11

hello啊&#xff0c;各位观众姥爷们&#xff01;&#xff01;&#xff01;本牛马baby今天又来了&#xff01;哈哈哈哈哈嗝&#x1f436; Java中是引用传递还是值传递&#xff1f; 在 Java 中&#xff0c;方法参数传递是通过 值传递 的方式实现的&#xff0c;但这可能会引起一…

VsCode对Arduino的开发配置

ps&#xff1a;我的情况是在对esp32进行编译、烧录时&#xff0c;找不到按钮&#xff0c;无法识别Arduino文件&#xff0c;适合已经有ini文件的情况。 1.在vscode中安装拓展 2.打开设置&#xff0c;点击右上角&#xff0c;转到settings.json文件 3.复制以下代码并保存 {"…

Apache Hop从入门到精通 第一课 揭开Apache Hop神秘面纱

一、Apache Hop是什么&#xff1f; 1、Apache Hop&#xff0c;简称Hop&#xff0c;全称为Hop Orchestration Platform&#xff0c;即Hop 工作编排平台&#xff0c;是一个数据编排和数据工程平台&#xff0c;旨在促进数据和元数据编排的所有方面。Hop让你专注于你想要解决的问题…

模拟SpringIOCAOP

一、IOC容器 Ioc负责创建&#xff0c;管理实例&#xff0c;向使用者提供实例&#xff0c;ioc就像一个工厂一样&#xff0c;称之为Bean工厂 1.1 Bean工厂的作用 先分析一下Bean工厂应具备的行为 1、需要一个获取实例的方法&#xff0c;根据一个参数获取对应的实例 getBean(…

基于ILI9341液晶屏+STM32U5单片的显示试验

试验要求&#xff1a; 1、通过串口&#xff0c;下发两个命令 STR和PIC&#xff1b; 2、STR模式&#xff1a; &#xff08;1&#xff09;串口输入什么&#xff0c;屏幕上显示什么 &#xff08;2&#xff09;如果屏幕满&#xff0c;自动下滚 &#xff08;3&#xff09;输入回车&a…