Qt Theme —— 纯 qss 的 Qt 主题

作者:hubenchang0515日期:2025/10/5

#Qt Theme —— 纯 qss 的 Qt 主题

源码地址:https://github.com/hubenchang0515/QtTheme/

Qt Theme 是一个纯 qss 的 Qt 主题项目,能够极为简单对已有项目的风格进行改进。

支持 C++、PyQt5、PyQt6、PySide2、PySide6,并以 WebAssembly 的方式在 GitHub Pages 上发布。

#安装

这里演示一下在 Python 上的使用,首先进行安装:

1pip install QtTheme
2

#演示

#原生样式及代码

让 Deep Seek 随便帮我写个界面作为示例:

1import sys
2from PySide6.QtWidgets import *
3from PySide6.QtGui import QPixmap
4from PySide6.QtCore import Qt, QTimer
5
6class DemoWindow(QMainWindow):
7    def __init__(self):
8        super().__init__()
9        self.setWindowTitle("PyQt Widget 演示界面")
10        self.setGeometry(100, 100, 800, 600)
11        
12        # 创建中心widget和主布局
13        central_widget = QWidget()
14        self.setCentralWidget(central_widget)
15        main_layout = QVBoxLayout(central_widget)
16
17        # 添加功能区域
18        self.create_input_section(main_layout)
19        self.create_selection_section(main_layout)
20        self.create_display_section(main_layout)
21        self.create_progress_section(main_layout)
22        
23        # 添加状态栏
24        self.statusBar().showMessage("就绪")
25
26        # 初始化进度条
27        self.progress_value = 0
28        self.update_progress()
29
30    def create_input_section(self, layout):
31        group = QGroupBox("输入控件")
32        grid = QGridLayout()
33
34        # 文本输入
35        self.line_edit = QLineEdit()
36        self.line_edit.setPlaceholderText("单行文本输入...")
37        grid.addWidget(QLabel("单行文本:"), 0, 0)
38        grid.addWidget(self.line_edit, 0, 1)
39
40        # 多行文本
41        self.text_edit = QTextEdit()
42        self.text_edit.setPlaceholderText("多行文本输入...")
43        grid.addWidget(QLabel("多行文本:"), 1, 0)
44        grid.addWidget(self.text_edit, 1, 1)
45
46        # 数字输入
47        self.spin_box = QSpinBox()
48        self.spin_box.setRange(0, 100)
49        grid.addWidget(QLabel("数字输入:"), 2, 0)
50        grid.addWidget(self.spin_box, 2, 1)
51
52        group.setLayout(grid)
53        layout.addWidget(group)
54
55    def create_selection_section(self, layout):
56        group = QGroupBox("选择控件")
57        hbox = QHBoxLayout()
58
59        # 复选框
60        vbox = QVBoxLayout()
61        self.check1 = QCheckBox("选项1")
62        self.check2 = QCheckBox("选项2")
63        vbox.addWidget(self.check1)
64        vbox.addWidget(self.check2)
65        hbox.addLayout(vbox)
66
67        # 单选框
68        vbox = QVBoxLayout()
69        self.radio1 = QRadioButton("单选1")
70        self.radio2 = QRadioButton("单选2")
71        self.radio1.setChecked(True)
72        vbox.addWidget(self.radio1)
73        vbox.addWidget(self.radio2)
74        hbox.addLayout(vbox)
75
76        # 下拉列表
77        self.combo = QComboBox()
78        self.combo.addItems(["选项A", "选项B", "选项C"])
79        hbox.addWidget(self.combo)
80
81        group.setLayout(hbox)
82        layout.addWidget(group)
83
84    def create_display_section(self, layout):
85        group = QGroupBox("显示控件")
86        hbox = QHBoxLayout()
87
88        # 标签
89        self.label = QLabel("这是一个标签")
90        self.label.setAlignment(Qt.AlignCenter)
91        self.label.setStyleSheet("border: 1px solid gray; padding: 10px;")
92        hbox.addWidget(self.label)
93
94        # 图片显示
95        pixmap = QPixmap(100, 50)
96        pixmap.fill(Qt.blue)
97        image_label = QLabel()
98        image_label.setPixmap(pixmap)
99        hbox.addWidget(image_label)
100
101        # 列表控件
102        self.list_widget = QListWidget()
103        self.list_widget.addItems(["项目1", "项目2", "项目3"])
104        hbox.addWidget(self.list_widget)
105
106        group.setLayout(hbox)
107        layout.addWidget(group)
108
109    def create_progress_section(self, layout):
110        group = QGroupBox("进度控件")
111        vbox = QVBoxLayout()
112
113        # 进度条
114        self.progress_bar = QProgressBar()
115        self.progress_bar.setValue(0)
116        vbox.addWidget(self.progress_bar)
117
118        # 滑块
119        self.slider = QSlider(Qt.Horizontal)
120        self.slider.setRange(0, 100)
121        self.slider.valueChanged.connect(self.on_slider_changed)
122        vbox.addWidget(self.slider)
123
124        # 控制按钮
125        btn_layout = QHBoxLayout()
126        self.start_btn = QPushButton("开始进度")
127        self.start_btn.clicked.connect(self.start_progress)
128        self.reset_btn = QPushButton("重置")
129        self.reset_btn.clicked.connect(self.reset_progress)
130        btn_layout.addWidget(self.start_btn)
131        btn_layout.addWidget(self.reset_btn)
132
133        vbox.addLayout(btn_layout)
134        group.setLayout(vbox)
135        layout.addWidget(group)
136
137    def on_slider_changed(self, value):
138        self.progress_bar.setValue(value)
139        self.statusBar().showMessage(f"滑块值: {value}")
140
141    def start_progress(self):
142        self.timer = QTimer()
143        self.timer.timeout.connect(self.update_progress)
144        self.timer.start(100)
145
146    def update_progress(self):
147        self.progress_value += 1
148        if self.progress_value > 100:
149            self.timer.stop()
150            return
151        self.progress_bar.setValue(self.progress_value)
152        self.slider.setValue(self.progress_value)
153
154    def reset_progress(self):
155        self.progress_value = 0
156        self.progress_bar.setValue(0)
157        self.slider.setValue(0)
158
159if __name__ == "__main__":
160    app = QApplication(sys.argv)
161    window = DemoWindow()
162    window.show()
163    sys.exit(app.exec())
164

运行起来看看:

#设置全局样式

导入 QtTheme 并设置样式:

1import QtTheme.PySide6 as QtTheme
2
3class DemoWindow(QMainWindow):
4    def __init__(self):
5        # 省略...
6
7        # 设置全局样式
8        self.setStyleSheet(QtTheme.getThemeStyle('Flat', 'Dark', 'Blue', 'Pink'))
9

#设置颜色

最后根据需要,通过 QWidget.setProperty 对 widgets 设置颜色:

1    def create_progress_section(self, layout):
2        # 省略 ...
3
4        # 给按钮设置颜色
5        self.start_btn.setProperty("Color", "Primary")
6        self.reset_btn.setProperty("Color", "Danger")
7

#导出资源

你也可以不安装 QtTheme,而是通过 在线页面 导出资源文件, 通过 RCC 将其加入你的项目:

1pyside6-rcc -o resource.py QtTheme.qrc
2

只需要修改导入方式,其余代码一致:

1from PySide6.QtCore import QFile
2import resource  # 导入生成的 resource.py
3
4class DemoWindow(QMainWindow):
5    def __init__(self):
6        # 省略...
7
8        qss = QFile(":/QtTheme/theme/Flat/Dark/Blue/Pink.qss")
9        qss.open(QFile.OpenModeFlag.ReadOnly)
10        self.setStyleSheet(qss.readAll().data().decode())
11

Qt Theme —— 纯 qss 的 Qt 主题》 是转载文章,点击查看原文


相关推荐


零基础从头教学Linux(Day 43)
小白银子2025/10/4

Nginx实现跨域与防盗链配置指南 四、 Nginx配置跨域 CORS 4.1 跨域的定义 同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。通常不允许不同源间的读操作。 4.2 同源的定义 如果两个页面的协议,端口(如果有指定)和域名都相同,则两个页面具有相同的源。 与 URL http://store.company.com/dir/page.html 的源进行对比的示例: http://store.comp


C语言实战项目:贪吃蛇(1)
高山有多高2025/10/3

前言:         通过持续数月的C语言系统学习,我们已经掌握了包括指针操作、结构体使用、文件IO等核心编程能力。为了检验学习成果并提升实战经验,在本篇技术博客中,我将带领大家开发一个具有里程碑意义的经典游戏项目 -- 贪吃蛇。          温馨提示:本篇博客为贪吃蛇游戏的前言准备。          一、贪吃蛇游戏效果演示   游戏效果演示: 二、贪吃蛇游戏设计          2.1 贪吃蛇游戏的最终目标            使⽤C


手把手部署 HFish 蜜罐:从防火墙配置到登录使用,新手也能轻松上手
着迷不白2025/10/2

​   在网络安全防护中,蜜罐工具能帮我们主动探测攻击行为,而 HFish 作为一款轻量易用的开源蜜罐,深受运维和安全从业者青睐。今天就带大家从 0 到 1 完成 HFish 的部署,全程步骤清晰,即使是新手也能跟着操作 —— 说不定部署完这套流程,老板看到规范的防护配置,还得给你加两千块工资呢!   一、前置准备:配置防火墙,开放关键端口 HFish 运行需要两个核心 TCP 端口:4433 端口用于 Web 管理界面访问,4434 端口用于节点与管理端的通信。为避免端口被防火墙拦截,我们需要


iOS 26 系统流畅度检测 从视觉特效到帧率稳定的实战策略
2501_916013742025/10/2

iOS 26 推出的 Liquid Glass 视觉语言,带来了全新的界面风格和动效体验,同时也给系统的渲染、合成、动画处理带来更高要求。在部分用户反馈中,升级 iOS 26 后出现系统卡顿、触控延迟、应用滑动不顺畅等问题。 要判断 iOS 26 是否真的“流畅”或在哪些场景有退化,需要有一套严谨的检测流程,而不是凭印象。 一、影响 iOS 26 流畅度的系统变化与挑战点 在 iOS 26 中,以下几个系统/界面变动是最可能牵扯到流畅性的问题点: Liquid Glass 界面开销 新系统的大


范式革命:RDMA 如何让网络成为 “分布式内存总线”
apple_ttt10/2/2025

摘要: RDMA技术通过内存访问范式革命,绕开远程CPU干预,实现设备间直接数据交互,显著降低延迟。其三大协议(InfiniBand、RoCE、iWARP)在性能、成本和兼容性上各有取舍:InfiniBand追求极致性能但成本高;RoCEv2兼容以太网但需精细配置;iWARP基于TCP,性能受限。RDMA虽解决了CPU瓶颈,但异构设备间的缓存一致性问题仍未解决,成为分布式计算向“单机化”演进的关键障碍。未来需结合CXL等一致性协议进一步突破。


学习Python中Selenium模块的基本用法(18:使用ActionChains操作鼠标)
gc_229910/1/2025

学习并验证使用Selenium模块的ActionChains操作鼠标的基本用法


在 VSCode 中运行 Vue.js 项目
小二爱编程·9/30/2025

这篇教程详细介绍了如何在VSCode中运行Vue.js项目。首先需要安装Node.js、Vue CLI和VSCode,然后通过Vue CLI创建新项目并安装依赖。接着在VSCode中打开项目文件夹,安装推荐的插件(如Volar)。最后使用npm run serve命令启动开发服务器,在浏览器访问即可查看运行效果。教程还说明了项目调试方法,包括自动刷新和断点调试。整个过程详细易懂,适合前端开发者和初学者学习使用VSCode开发Vue.js项目。


Flutter 开发:应用颜色使用 Class 还是 Enum?—— 你应该选择哪一个?
JarvanMo2025/10/7

在开始一个新的 Flutter 项目时,第一步就是定义你的颜色调色板(color palette) 。一个一致且可维护的颜色系统不仅能保持你的设计简洁,还能让你的应用扩展变得更加容易。 但这里有一个开发者经常面临的常见问题: 👉 在 Flutter 中,你是应该使用带有静态常量的 Class(类) ,还是使用 **Enum(枚举)**来管理颜色呢? 随着 Dart 2.17 中**增强型枚举(enhanced enums)**的到来,答案变得更有趣了。下面我们通过示例、优缺点来探讨这两种方法。


JavaScript性能优化实战:从指标到落地的全链路方案
weixin_439647792025/10/8

JavaScript性能优化实战:从指标到落地的全链路方案 实际项目中,性能优化往往不是单一手段的应用,而是“指标监测-瓶颈定位-方案实施-效果验证”的全链路过程。本文将结合电商、管理系统等真实场景,提供可落地的性能优化闭环方案。 一、性能指标体系:从“感觉卡顿”到“数据说话” 性能优化的第一步是建立可量化的指标体系,避免凭主观感受判断优化效果。前端核心性能指标可分为三类: 1. 加载性能指标 LCP(最大内容绘制):衡量首屏加载速度,目标值<2.5sTTI(交互时间):页面可完全交互


还在纠结用v-if还是v-show?看完这篇彻底搞懂Vue渲染机制!
良山有风来2025/10/10

你是不是也曾经在写Vue时纠结过:这里到底该用v-if还是v-show? 或者更惨的是,明明代码逻辑没问题,列表渲染却总是出现各种诡异bug:删除一个项,结果删错了;切换数据,页面状态全乱了... 别担心,今天我就来帮你彻底搞懂Vue的条件渲染和列表渲染,让你写出更优雅、更高效的代码! v-if和v-show:看似相似,实则大不相同 先来看个最简单的例子: <!-- v-if 的用法 --> <div v-if="isVisible">我会在条件为真时渲染</div> <!-- v-show

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0