尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

QSS伪类选择器详解:Qt界面状态样式实战指南

QSS伪类选择器详解:Qt界面状态样式实战指南 1. 先从使用场景说说伪类选择器在Qt的界面开发里做样式的人都有个感觉静态样式好写动态状态难调。按钮要悬停变蓝、按下变深、禁用变灰列表选中要高亮、失焦要变淡复选框勾选要换勾、半选要显示横线输入框聚焦要亮边框、只读要变灰底。这些东西如果全靠信号槽去动态改setStyleSheet代码会乱到没法看而且状态切换还会闪屏。QSS的伪类选择器就是专门用来解决这个问题的。伪类选择器说白了就是“给控件的某个状态单独写样式”。它不要求你写任何C逻辑只要在QSS里用冒号把状态标出来Qt的样式引擎会自动在鼠标悬停、按下、选中、禁用等时刻去匹配对应的规则。这和我们网页里写CSS的:hover、:focus是同一个思路但Qt根据自身控件体系又扩展出了一大堆专属状态比如:checked、:selected、:on、:off。这篇文章假设你已经会写基础的QSS会设置背景色、边框、圆角、字体也见过QPushButton这种选择器写法。如果还不太熟也没关系跟着这篇文章走一遍伪类的用法你以后调控件交互状态会非常顺手。我尽量把每个伪类的适用场景、写法、坑都掰开讲清楚文章里的代码你直接贴到项目里就能看效果。1.1 用一个例子理解伪类到底做了什么先看一段最简单的代码QPushButton { background-color: #e0e0e0; } QPushButton:hover { background-color: #90caf9; } QPushButton:pressed { background-color: #1e88e5; }当鼠标悬停在按钮上时QPushButton:hover里的背景色会生效鼠标按下时QPushButton:pressed里的背景色会覆盖 hover 的效果鼠标移开又恢复默认的灰色。这里有几个初学者容易绕晕的点。第一这些规则不是互相排斥的而是“覆盖”的关系。按下按钮时鼠标必然还在按钮上所以pressed和hover两个状态同时成立至于最终显示哪个颜色Qt 会根据选择器的精确程度和声明顺序来决定。第二:hover和:pressed这类伪类是动态的用户不操作时它们根本不参与匹配所以不影响默认状态的渲染。第三伪类可以在同一个控件选择器上叠加多个比如QPushButton:hover:pressed表示“悬停且按下”同时成立时才匹配。理解了这个覆盖机制你就能明白为什么有些新手写QSS会遇到“hover没反应”“pressed被hover盖住”之类的怪问题后面我会专门讲排查方法。1.2 QSS伪类选择器的整体分类Qt官方文档把伪类分成几类我帮你归拢一下交互状态类:hover、:pressed、:focus这三个是动态的跟随鼠标和键盘焦点变化。开关状态类:checked、:unchecked、:indeterminate、:on、:off用于复选框、单选按钮、可检查的按钮、开关控件。可用性状态类:enabled、:disabled、:read-only、:read-write、:editable、:non-editable。选中项状态类:selected、:current、:active用于列表、树、表格里的项。窗口/位置状态类:top-level、:window、:first、:last、:only-one、:has-children等相对冷门但在定制菜单和树控件时会用到。特殊控件状态类:default、:flat、:open、:closed等。不需要一次全部记住但你要知道有这些分类。实际项目里最常用的是hover、pressed、focus、checked、disabled、selected这几个先把它们的属性作用范围吃透其余用到时查文档就行。2. 逐个拆解高频伪类的实际写法这一节我按“鼠标交互、焦点、开关、选中项”四个场景来讲每个伪类我都给你写清适用控件、注意事项和可以直接跑的代码。这是我的经验笔记不是文档翻译。2.1 鼠标状态hover 和 pressed:hover是鼠标悬停在控件上时的样式几乎适用于所有可见控件。:pressed是鼠标按下未释放时的状态常见于按钮和可点击的项。QPushButton { background-color: #f5f5f5; border: 1px solid #ccc; padding: 6px 16px; border-radius: 4px; } QPushButton:hover { background-color: #e3f2fd; border-color: #64b5f6; } QPushButton:pressed { background-color: #90caf9; border-color: #1e88e5; padding-top: 7px; padding-bottom: 5px; }这里有几个细节你要注意。一是边框和圆角不要随意缺。很多新手的按钮在hover时只改背景色把原来的border值漏掉了结果按钮尺寸突然大了一圈因为默认边框从无到有。所以你在设置hover时最好把border也带上哪怕只是换颜色。二是按下时移动文字是模拟“物理按下”的常见手法。做法是pressed状态下调整padding-top和padding-bottom让文字往下偏移1~2像素。这个细节非常实用很多看起来精致的按钮都是这么做的。三是把hover规则写在pressed之前。因为pressed状态同时满足hover如果先写了QPushButton:pressed再写QPushButton:hover鼠标按下时hover的优先级会更高出现“按不下去”的视觉问题。虽然实际项目中我很少依赖顺序习惯直接写成QPushButton:hover:pressed这样最保险。QPushButton:hover:pressed { background-color: #ff7043; }这种写法表达的意思是“悬停且按下”两条条件缺一不可避免和其他状态互相抢。2.2 焦点状态focus 与文本框高亮:focus表示控件获得键盘焦点最常见的应用是输入框聚焦时显示高亮边框提升交互反馈。QLineEdit { border: 1px solid #d0d0d0; border-radius: 4px; padding: 4px 8px; background: white; } QLineEdit:focus { border: 1px solid #1976d2; background: #fafeff; }这个用法很简单但有一个容易忽略的点当你的焦点样式只改了边框颜色边框宽度又不同输入框会轻微跳动。解决办法是默认状态就声明border: 1px solid #d0d0d0聚焦时只换颜色宽度保持一致。另外QComboBox、QSpinBox这类复合控件在使用:focus时你可能会发现边框高亮了但内部的输入框没反应。这时可以把焦点样式直接作用在下拉框的line edit部分或者用QComboBox:focus和QComboBox::drop-down:focus组合去覆盖子控件。一个进阶技巧:focus 不一定要配边框配合 box-shadow 做外发光效果也很棒。Qt 的盒子阴影和CSS不完全一样属性写法相对简陋但边框颜色加粗的“伪外发光”也能达到类似效果。QLineEdit:focus { border: 2px solid #42a5f5; padding: 3px 7px; }注意调 padding避免因为边框从1px变成2px导致文字偏移。2.3 开关状态checked、unchecked、indeterminate:checked适用于所有“可勾选”的控件QCheckBox、QRadioButton、可检查的QPushButtonsetCheckable(true)。:unchecked是它的对立面:indeterminate是三态复选框的“半选”状态适合树形结构的父节点。给复选框自定义勾选图标是一个非常经典的伪类应用QCheckBox::indicator { width: 18px; height: 18px; border: 1px solid #bdbdbd; border-radius: 3px; background: white; } QCheckBox::indicator:hover { border-color: #1976d2; } QCheckBox::indicator:checked { background-color: #1976d2; border-color: #1976d2; image: url(:/images/check_white.png); } QCheckBox::indicator:indeterminate { background-color: #90caf9; border-color: #1976d2; image: url(:/images/indeterminate_line.png); }这里要注意::indicator是子控件选择器它和伪类可以叠加顺序无所谓但语法上要写成分开的“冒号冒号”和“冒号”。我自己在项目里不习惯用图片画勾因为图片在不同分辨率下会糊。更稳的方案是直接用字符或者简单形状但QSS本身画不出对勾形状所以多数项目还是会准备一张小的勾选图标。这里给你一个避坑建议图标尺寸宁小勿大最好和indicator区域差不多四周留点白不然视觉上会贴边。单选框同理区别是圆角属性不同QRadioButton::indicator { width: 16px; height: 16px; border-radius: 8px; border: 1px solid #bbb; } QRadioButton::indicator:checked { border: 5px solid #1976d2; background: white; }2.4 可用状态enabled、disabled、read-only:enabled和:disabled非常简单但很多人写禁用样式时只改文字颜色不改背景和边框导致用户根本看不出按钮不可点。QPushButton:disabled { color: #aaa; background-color: #f5f5f5; border: 1px solid #ddd; }要注意的是QPushButton:disabled写在后面会覆盖前面普通状态的颜色但它不会覆盖QPushButton:hover:disabled这样的组合。如果你希望禁用状态下连鼠标悬停也不变就需要单独写QPushButton:disabled { color: #aaa; background: #f5f5f5; } QPushButton:hover:disabled { background: #f5f5f5; }:read-only和:read-write是文本输入控件才有的状态比如QLineEdit。在Qt 5.7之后的版本支持比较稳定。设置了setReadOnly(true)后输入框就匹配:read-only这时你可以把背景改成浅灰并去掉聚焦高亮QLineEdit:read-only { background: #fafafa; color: #999; } QLineEdit:read-only:focus { border: 1px solid #d0d0d0; }如果不写:read-only:focus这一条只读输入框仍然会在点击时显示聚焦边框视觉上让人觉得还能编辑很误导用户。2.5 列表和树里的选中状态selected、current、active在QListWidget、QTableWidget、QTreeWidget里最常用的伪类是:selected表示某项被选中。它的常见写法要配合::item子控件QListWidget::item { padding: 6px 8px; border-radius: 4px; } QListWidget::item:hover { background-color: #f5f5f5; } QListWidget::item:selected { background-color: #e3f2fd; color: #1976d2; }这里有个失焦变色的经典问题列表在失去焦点后:selected仍然成立但默认高亮颜色会变灰看起来很丑。解决方法是同时匹配:selected:active和:selected:!active或者直接把QListWidget的focusPolicy调整一下。QListWidget::item:selected:active { background-color: #e3f2fd; color: #1976d2; } QListWidget::item:selected:!active { background-color: #eeeeee; color: #616161; }:!active是:not(:active)的简写意思是“窗口非激活状态”。:active在这里表示“选中项所在窗口是激活窗口”和控件的焦点状态是两回事。这两个伪类组合后列表项在失焦时也有合理的高亮反馈。::item:selected里还有一个容易被忽略的属性selection-background-color和selection-color。如果你在普通QListWidget上设置了这两个属性它们的作用优先级可能高于::item:selected的背景色。排查样式不生效时记得先把这两个属性清掉。3. 组合、叠加与优先级这才是真正的实战单写一个:hover谁都会实际项目里我们经常要处理“多个状态同时满足”“同一控件在不同业务场景下用不同样式”“继承下来的冲突”这类复杂问题。这一节是全文含金量最高的部分我建议你仔细看。3.1 多伪类叠加与子控件组合多伪类叠加就是连续写多个状态比如QPushButton:hover:focus { border-color: #ff9800; } QComboBox::drop-down:hover { background-color: #e0e0e0; }第一条是“悬停且聚焦”时的按钮样式第二条是“下拉框右侧箭头按钮悬停”时的样式。子控件选择器::drop-down、::indicator、::item和伪类选择器是正交的你可以自由组合。我把常见的组合列一下组合写法适用场景QPushButton:pressed按钮按下QPushButton:checked可勾选按钮处于选中QPushButton:checked:hover勾选状态且悬停QComboBox::drop-down:pressed下拉箭头按下QSpinBox::up-button:pressed数字框上箭头按下QTreeWidget::item:selected树节点选中QMenu::item:selected菜单项选中悬停QScrollBar::handle:vertical:hover垂直滚动条滑块悬停我遇到过很多次“按钮又选中又禁用”的场景。比如一个工具按钮既是 checkable 又被 setEnabled(false)这时你写QPushButton:checked还是QPushButton:disabled都会生效到底显示哪个颜色这就要看命令顺序和优先级后面会讲。3.2 属性选择器实现“类样式”QSS虽然没有CSS里的.class类选择器但可以用属性选择器模拟出类似效果。这是我最推荐的美化方案尤其是当你需要做“主按钮、次按钮、危险按钮”这种成套样式时。先在C侧给按钮打标签auto *btnPrimary new QPushButton(确定, this); btnPrimary-setProperty(level, primary); auto *btnDanger new QPushButton(删除, this); btnDanger-setProperty(level, danger);然后在QSS里用属性选择器匹配QPushButton { background: #f5f5f5; border: 1px solid #ccc; border-radius: 4px; padding: 6px 16px; } QPushButton[levelprimary] { background: #1976d2; color: white; } QPushButton[levelprimary]:hover { background: #1565c0; } QPushButton[leveldanger] { background: #d32f2f; color: white; } QPushButton[leveldanger]:hover { background: #c62828; }这样你可以在代码里无脑创建不同级别的按钮样式全部由QSS统一管理。但这里有一个大坑用setProperty修改属性后必须重新刷新样式否则新属性不会生效。正确姿势是btnPrimary-setProperty(level, primary); btnPrimary-style()-unpolish(btnPrimary); btnPrimary-style()-polish(btnPrimary); btnPrimary-update();不刷新的后果就是属性值变了界面却还是老样子。这个问题我碰到过不止一次调试半天才发现是没调unpolish。如果想更接近CSS的class写法可以用class作为属性名btnPrimary-setProperty(class, btn btn-primary);然后在QSS里用QPushButton[class~btn-primary] { ... }~是“包含某个词”的匹配方式和CSS的class~btn-primary一致。用这个方式你甚至可以给一个控件同时打多个样式标签。3.3 优先级为什么我的样式没有生效QSS的优先级规则和CSS非常像但Qt文档没有给出一份完整的官方权重说明我按多年踩坑经验给你总结一套“够用”的规则。一个选择器的优先级由三部分组成ID选择器、类/伪类/属性选择器、类型选择器。ID选择器#myButton权重级别最高。类/伪类/属性选择器[levelprimary]、:hover、:selected权重中等。类型选择器QPushButton、QLineEdit、QComboBox::drop-down权重最低。举个例子QPushButton { background: gray; /* 类型选择器 */ } QPushButton:hover { background: blue; /* 类型 伪类优先级更高 */ } #myButton:hover { background: red; /* ID 伪类最高 */ }三条规则同时命中的时候#myButton:hover胜出。如果优先级相同则“后定义的覆盖先定义的”这点和CSS一致。所以我在写QSS时会习惯性地把基础状态放在最上面然后是hover、pressed最后才是各种特殊状态保证文件阅读顺序和优先级顺序一致出问题也好查。还有一个隐藏规则是控件自带的QSS属性可能覆盖本地样式。比如你在QLineEdit上直接设了setStyleSheet(background:yellow)那整个QSS文件里的QLineEdit背景都不会生效因为内联样式的优先级高于外部样式表。这类问题排查起来很费劲建议在代码里坚持“样式只走QSS文件”避免动态拼接setStyleSheet。4. 一套完整案例从0调出漂亮的按钮、输入框和列表理论讲再多不如撸一套完整的实际效果。这里我仿照一个后台管理系统的登录界面把伪类选择器综合用一遍。你照着建一个Qt Widgets工程把代码贴进去马上能看到效果。4.1 界面结构和目标效果我创建一个主窗口上面放三个控件一个QLineEdit密码输入框要求聚焦时有蓝色边框只读状态有灰色底。一个QCheckBox记住密码要求自定义勾选图标悬停边框变蓝选中后蓝底白勾。三个QPushButton分别是登录、注册、退出登录。登录按钮是主按钮注册按钮是普通按钮退出登录按钮在悬停时变红。控件创建代码大致如下#include QWidget #include QLineEdit #include QCheckBox #include QPushButton #include QVBoxLayout QWidget *panel new QWidget; auto *passwordEdit new QLineEdit; auto *rememberCheck new QCheckBox(记住密码); auto *loginBtn new QPushButton(登 录); auto *registerBtn new QPushButton(注 册); auto *logoutBtn new QPushButton(退出登录); passwordEdit-setPlaceholderText(请输入密码); passwordEdit-setEchoMode(QLineEdit::Password); loginBtn-setProperty(level, primary); registerBtn-setProperty(level, normal); logoutBtn-setProperty(level, danger); auto *layout new QVBoxLayout(panel); layout-addWidget(passwordEdit); layout-addWidget(rememberCheck); layout-addWidget(loginBtn); layout-addWidget(registerBtn); layout-addWidget(logoutBtn);4.2 完整QSS配置把下面这段存成style.qss在main函数里加载后设置给QApplicationQWidget { background-color: #f7f8fa; font-family: Microsoft YaHei, PingFang SC, sans-serif; font-size: 14px; } /* 输入框通用状态 */ QLineEdit { background: white; border: 1px solid #d0d7de; border-radius: 6px; padding: 8px 12px; selection-background-color: #1976d2; selection-color: white; } QLineEdit:hover { border-color: #b0b7bf; } QLineEdit:focus { border: 1px solid #1976d2; background: #fafcff; } QLineEdit:read-only { background: #f0f2f5; color: #8c8c8c; } QLineEdit:read-only:focus { border: 1px solid #d0d7de; } /* 复选框通用状态 */ QCheckBox { spacing: 8px; } QCheckBox::indicator { width: 18px; height: 18px; border: 1px solid #bdbdbd; border-radius: 4px; background: white; } QCheckBox::indicator:hover { border-color: #1976d2; } QCheckBox::indicator:checked { background-color: #1976d2; border-color: #1976d2; image: url(:/icons/check_white.png); } QCheckBox::indicator:pressed { background-color: #90caf9; } /* 按钮基础与状态 */ QPushButton { background-color: #ffffff; border: 1px solid #d0d7de; border-radius: 6px; padding: 8px 16px; min-width: 80px; } QPushButton:hover { background-color: #f3f4f6; border-color: #b0b7bf; } QPushButton:pressed { background-color: #e5e7eb; padding-top: 9px; padding-bottom: 7px; } QPushButton:disabled { color: #aaa; background-color: #f5f5f5; border-color: #e0e0e0; } /* 主按钮 */ QPushButton[levelprimary] { background-color: #1976d2; border-color: #1976d2; color: white; } QPushButton[levelprimary]:hover { background-color: #1565c0; border-color: #1565c0; } QPushButton[levelprimary]:pressed { background-color: #0d47a1; } QPushButton[levelprimary]:disabled { background-color: #a0c4e8; border-color: #a0c4e8; color: #e3f2fd; } /* 危险按钮 */ QPushButton[leveldanger]:hover { background-color: #fff3f3; border-color: #d32f2f; color: #d32f2f; } QPushButton[leveldanger]:pressed { background-color: #fbe0e0; border-color: #c62828; color: #c62828; } /* 列表例子下拉框与QListWidget通用高亮 */ QListWidget::item { padding: 8px 12px; border-radius: 6px; } QListWidget::item:hover { background-color: #f5f7fa; } QListWidget::item:selected { background-color: #e8f0fe; color: #1967d2; } QListWidget::item:selected:!active { background-color: #eeeeee; color: #616161; }加载QSS的代码QFile file(:/style.qss); file.open(QFile::ReadOnly); QString styleSheet QLatin1String(file.readAll()); qApp-setStyleSheet(styleSheet);注意如果你用了自定义资源文件:/style.qss需要和你 .qrc 里的路径一致。4.3 调试与效果验收技巧代码贴完后建议你用QStyleSheetStyle自带的调试方法看不生效的原因在main函数里设一个环境变量或直接用qDebug输出选中控件样式的警告。Qt在样式表解析出错时通常会在控制台打印一行Could not parse stylesheet of object ...这行信息非常关键。还有一个很实用的小技巧临时用一个纯色块代替图片。如果你发现复选框的勾选图片失效先别怀疑文件路径直接把image: url(...)去掉改成background-color: red如果能显示红色说明图片加载有问题如果连红色都不显示那就是选择器或者状态匹配的问题。用这种“二分法”定位比盯着QSS反复看快得多。另外我建议在每个状态设计完成后都手动操作一遍交互路径鼠标慢慢从控件上滑过观察 hover 是否触发。按住鼠标不松开观察 pressed 是否生效。关闭窗口再重新打开观察禁用、选中状态是否被正确回复。状态切换闪动的一个常见原因是QSS里不同状态下的圆角或者边框阴影不一致导致Qt反复重绘。虽然不至于崩但肉眼能察觉。所以生产环境里我通常保持 border、border-radius 一致只改颜色和一点点padding。5. 常见问题与排坑实录伪类选择器本身不难难的是各种“莫名其妙”不生效。我把这些年被问得最多、自己也踩过的问题整理成一张“速查表”顺便说说我的排查思路。5.1 样式不生效先按顺序查这几处第一选择器写错没。QSS对控件名大小写敏感QPushButton写成了QpushButton完全无效子控件该用双冒号的少写一个冒号也不生效。Qt在控制台输出的解析警告要认真看。第二优先级被覆盖没有。你的规则写对了但可能被后面优先级相同的规则覆盖或者被某个setStyleSheet动态设置的样式覆盖。排查方法很简单先全局搜索一下有没有给同一个控件动态设置过样式有的话优先删掉。第三属性名或属性值不对。QSS虽然像CSS但很多属性名不一样。比如文字颜色是color背景是background-color这些没问题但盒子阴影、渐变等写法有Qt自己的限制。有时候属性名拼写正确但属性值里的单位写错比如把radius写成radius-pxQt会直接忽略该条。第四样式文件是否真的加载了。很多新手在QSS文件里写了半天发现一点效果没有结果是main函数里根本没调用setStyleSheet或者文件路径写错了。先qDebug打印一下读取的字符串确保非空。第五选择器匹配的控件层级问题。比如你写QWidget QPushButton { ... }意思是匹配“所有QWidget控件内部的QPushButton”。但如果你在顶层窗口直接放按钮窗口类名不是QWidget而是MainWindow那这条规则可能不生效因为类型选择器匹配的是类的继承关系。Qt样式表的类型选择器命名规则是匹配控件类名以及其子类但不匹配父类。换句话说QPushButton能匹配MyButton这种子类但QWidget不会自动匹配QMainWindow内部的所有子控件除非你写成后代选择器。5.2 伪类相关的常见错误:hover不生效大概率是鼠标事件被上层控件拦截了。比如你把按钮放进了QFrame又给QFrame设置了setAttribute(Qt::WA_TransparentForMouseEvents)或者是某些自绘控件把鼠标事件完全吞掉了。解决办法是给顶层容器设置setAttribute(Qt::WA_StyledBackground)或者检查一下鼠标事件转发逻辑。:pressed和:hover视觉冲突就是我在2.1里提到的顺序问题。建议写成QPushButton:hover:pressed同时把鼠标按下时不需要变动的属性留空。注意:hover:pressed和:pressed:hover是等价的但Qt里习惯把:pressed写后面阅读更直观。:checked对普通QPushButton不生效因为按钮默认不是可勾选的。要先用setCheckable(true)开启勾选能力。QAction放在QToolButton里时也要确保 action 的 checkable 属性为 true否则:checked永远不会匹配。:selected不生效很常见于QComboBox的列表项。QComboBox的下拉项本质上是一个QListView但因为平台差异有时必须额外设置view()-setStyleSheet(...)或者用QComboBox QAbstractItemView::item:selected这种写法。直接写QComboBox::item:selected有时不起作用我建议先写QComboBox QAbstractItemView::item:selected试试。单项高亮和整体高亮混淆发生在QTableWidget里。:selected匹配的是“项”不是“行”。如果你想要整行高亮需要在QStyledItemDelegate里处理QSS只负责单元格级。别花太多时间指望QSS做整行效果我试过收益太低了。5.3 几个实战小技巧第一个不刷新的属性切换。我前面提过setProperty后要unpolish/polish但如果你用QStyle的repolish整套刷新有时会造成闪烁。精准做法是只对单个控件刷新widget-style()-unpolish(widget); widget-style()-polish(widget); widget-update();第二个同一控件多状态的颜色继承问题。比如你给QPushButton设置了color: white在:hover里只改了背景色没有写color那文字颜色仍然是白色这是符合预期的。利用这个特性你可以在基础状态里统一定义文字颜色后续状态只改背景省去重复代码。第三个用!important突破优先级。QSS支持!important和CSS用法一样QPushButton:hover { background-color: #1976d2 !important; }加了!important后即使有更高优先级的规则也不容易覆盖它。但我不建议到处滥用它会让样式表变得难排查。我一般只在“必须覆盖内联样式”或者“被外部SDK强制带了一套QSS”的极端场景用。第四个窗口级别伪类的取舍。:active的用法比较反直觉它表示“当前激活窗口”常用于列表项高亮的失活配色。实际项目里为了规避不同平台对激活状态判定的差异我通常用:!active统一处理非激活配色这样列表在窗口失焦时不会出现刺眼的亮蓝块。6. 收尾的一点经验写到这里伪类选择器的核心部分基本都覆盖到了。我个人在实际项目里的习惯是先把基础状态和核心交互状态hover、pressed、focus、disabled的QSS写好再根据业务场景去补充selected、checked这类特殊状态。并且一定要求全组遵守“QSS进文件不进代码”的规矩setStyleSheet只用来做动态覆盖所有静态样式统一放在一个style.qss里管理。这样后期改主题、换配色只需要改一个文件全局生效省下来的联调时间非常可观。最后再分享一个小技巧写复杂QSS前先用Qt自带的QStyleSheet例子在Qt安装目录的Examples里能找到做实验配合QSS Editor工具实时预览会比直接在项目里改文件高效得多。像伪类这种靠交互触发的状态尤其适合在编辑器里快速验证因为项目里一遍遍跑起来滑鼠标调样式真的挺费时间的。
返回列表