当前位置:首页 > 技术 > 正文内容

基于深度学习的视觉检测项目中的动态样式表实现

访客 技术 2026年7月1日 1

动态样式表的基础知识: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: 文字颜色;
}

在样式表中,使用了"基底色"、"常规文字色"这样的伪变量,然后从"基底色"映射到"深蓝",再从"深蓝"映射到颜色值"#0f0f6e"。这样使用伪变量与通常的编程的变量的概念是很接近的,特别方便集中修改和复制移植。当然了,也可以在样式表和映射文件中不使用或部分使用伪变量,比如:

# 部分使用伪变量的映射文件
{
    "color_setting": {
        "基底色": "深蓝",
        "窗口色": "浅绿",
        "顶部标签色": "黑色",
        "按钮底色": #1a1a1a,
        "常规文字色": red
    }
}

上面的代码中,"#1a1a1a" 和 "red" 没有使用伪变量,而是用了QSS的标准格式。

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

这次把项目的目录结构做了一个修改,尝试在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()  # 设置窗口居中

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

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。