Qt界面美化之自定义qss样式表
原生的QT界面不好看,有时候需要根据美工的设计图修改样式。如果使用QML的话搞界面是快,但是QML有点儿吃内存,有时简单的功能还是用传统c++的widget方便些。好在有qss,传统界面也可以美化的。QSS称为Qt Style Sheets也就是Qt样式表,它是Qt提供的一种用来自定义控件外观的机制。QSS大量参考了CSS的内容,只不过QSS的功能比CSS要弱很多,体现在选择器要少,可以使用的QSS属性也要少很多,并且并不是所有的属性都可以用在Qt的所有控件上。
目标任务
以下以实例介绍下自定义样式的实现,如下图所示,实现下图的效果。

提供的美工资源有个关机的透明图标:![]()
如何实现?接下来详细介绍下。
详细步骤
一、新建qrc文件,添加和保存资源文件
首先新建个qrc资源文件,使用Qtcreater的话可以直接在菜单中找新建->资源文件(qrc)。当然这个文件也可以手工创建。文件内容如下image.qrc:
<RCC><qresource prefix="/"><file>qss/gray.css</file><file>image/shutdownicon.png</file><file>image/shutdownlogo.png</file><file>image/shutdownpushbutton.png</file><file>image/shutdownpushbuttonpress.png</file><file>image/spinner.png</file><file>image/tips.png</file><file>image/calendar.png</file></qresource>
</RCC>
在根目录里创建一个qss文件夹,里面创建全局样式表css文件。(建议这么搞,样式都统一放到样式表文件里,方便后续修改。不建议直接在界面上使用QtDesigner去改样式。)
二、新建css样式表文件
style.css样式文件内容如下:
QPalette{background:#e5e5e5;}QLabel,
QLineEdit,
QTextEdit,
QPlainTextEdit,
QGroupBox,
QComboBox,
QDateEdit,
QTimeEdit,
QDateTimeEdit,
QTreeView,
QListView,
QTableView,QLineEdit,
QTextEdit,
QPlainTextEdit {}QLabel#image1{/*background-image: url(:/image/shutdownlogo.png);*/
}QLabel#text1{color: #004695;font: 75 18pt "微软雅黑";
}QLineEdit[echoMode="2"] {lineedit-password-character: 9679;
}.QGroupBox {border: 1px solid #A9A9A9;border-radius: 5px;
}.QPushButton {border-style: none;border: 1px solid #A9A9A9;color: #FFFFFF;padding: 5px;/* min-height: 20px; *//* min-width: 30px; */border-radius: 40px;background: rgb(46,118,199);
}.QPushButton:hover {background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgb(46,118,199), stop:1 #C1C1C1);
}.QPushButton:pressed {background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #004695, stop:1 #004695);
}.QPushButton:disabled {color: #838383;background: #F4F4F4;
}.QPushButton#btnShutDown {background-image: url(:/image/shutdownicon.png);background-position: left;background-repeat: no-repeat;background-origin:content;padding-left:90px;text-align: right;padding-right:120px;font: 25 20pt "Microsoft YaHei";}.QPushButton#btnShutDown:pressed {background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #004695, stop:1 #004695);
}QCheckBox {color: #000000;spacing: 2px;
}QCheckBox::indicator {width: 20px;height: 20px;
}QRadioButton {color: #000000;spacing: 2px;
}QComboBox {/* border-style: none; *//* border: 1px solid #A9A9A9; */border-radius: 5px;
}QSpinBox {border-radius: 5px;
}
style.css文件内容解释,有点css基础的应该很容易看懂。最前面的一系列是统一设置控件的样式。
QLabel#image1{/*background-image: url(:/image/shutdownlogo.png);*/
}QLabel#text1{color: #004695;font: 75 18pt "微软雅黑";
}
这里的#后面跟的内容,就是你界面里指定的控件对象名称,如image1,text1等。
.QPushButton#btnShutDown:pressed {background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #004695, stop:1 #004695);
}
以上的:pressed设置按钮按下时的样式,hover是鼠标悬停上面的样式。
设置按钮的背景图片,关键属性:
1、background-position ----- 设置图标的位置
2、text-align-------------设置文本的位置
3、background-origin-------------相对于内容框来定位背景图像
如何使用
在mainWindow窗口实例化的地方,全局加载即可。
//设置指定样式static void setStyle(const QString &qssFile) {QFile file(qssFile);if (file.open(QFile::ReadOnly)) {QString qss = QLatin1String(file.readAll());qApp->setStyleSheet(qss);QString PaletteColor = qss.mid(20, 7);qApp->setPalette(QPalette(QColor(PaletteColor)));file.close();}}
MainWindow::MainWindow(QWidget *parent) :QWidget(parent), ui(new Ui::MainWindow) {ui->setupUi(this);setFixedSize(1280, 1024);//setWindowFlags(Qt::Window | Qt::FramelessWindowHint);myHelper::setStyle(":/qss/style.css");
}
整理了一个全局的辅助类,方便使用。
#ifndef MYHELPER_H
#define MYHELPER_H#include <QtCore>
#include <QtGui>#if (QT_VERSION > QT_VERSION_CHECK(5, 0, 0))#include <QtWidgets>#endifclass myHelper : public QObject {public:static void autoRunWithSystem(bool ifAutoRun, QString appName, QString appPath) {QSettings *reg = new QSettings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", QSettings::NativeFormat);if (ifAutoRun) {reg->setValue(appName, appPath);} else {reg->setValue(appName, "");}}//设置编码为UTF8static void setTextCode(const QString sForName = "UTF-8") {
#if (QT_VERSION <= QT_VERSION_CHECK(5, 0, 0))QTextCodec *codec = QTextCodec::codecForName(sForName);QTextCodec::setCodecForLocale(codec);QTextCodec::setCodecForCStrings(codec);QTextCodec::setCodecForTr(codec);
#endif}//设置指定样式static void setStyle(const QString &qssFile) {QFile file(qssFile);if (file.open(QFile::ReadOnly)) {QString qss = QLatin1String(file.readAll());qApp->setStyleSheet(qss);QString PaletteColor = qss.mid(20, 7);qApp->setPalette(QPalette(QColor(PaletteColor)));file.close();}}//加载中文字符static void setChinese() {QTranslator *translator = new QTranslator(qApp);translator->load(":/image/qt_zh_CN.qm");qApp->installTranslator(translator);}//判断是否是IP地址static bool isIP(const QString sIP) {QRegExp RegExp("((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)");return RegExp.exactMatch(sIP);}//延时static void sleep(int sec) {QTime dieTime = QTime::currentTime().addMSecs(sec);while (QTime::currentTime() < dieTime) {QCoreApplication::processEvents(QEventLoop::AllEvents, 100);}}//延时static int sleep1(int command, int sec, int *state) {int ret = 0;QTime dieTime = QTime::currentTime().addMSecs(sec);while (QTime::currentTime() < dieTime) {if (((0xC7 != command && 0xC1 != command) && (*state == 2)) ||((0xC7 == command || 0xC1 == command) && (*state == 3))) {return 1;}QCoreApplication::processEvents(QEventLoop::AllEvents, 100);}ret = 2;return ret;}//窗体居中显示static void moveFormToCenter(QWidget *frm) {int frmX = frm->width();int frmY = frm->height();QDesktopWidget dwt;int deskWidth = dwt.availableGeometry().width();int deskHeight = dwt.availableGeometry().height();QPoint movePoint(deskWidth / 2 - frmX / 2, deskHeight / 2 - frmY / 2);frm->move(movePoint);}
};#endif // MYHELPER_H
CMakeLists文件
由于习惯了使用cmake,以下附上cmake的QT工程配置,CMakeList.txt文件。
cmake_minimum_required(VERSION 3.21)
project(myapp)set(CMAKE_PREFIX_PATH "D:/Qt/Qtxx/xx.xx/msvc20xx/lib/cmake")add_definitions(-D_ENABLE_LOGGING
)##设置输出目录
set(BUILD_DIRECTORY "")
set(BUILD_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../build)
#################### QT dependencies ########################
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)set(QT_VERSION 5)
set(REQUIRED_LIBS Core Gui Network Widgets)
set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Gui Qt5::Network Qt5::Widgets)#################### set output directory ####################
set(BUILD_DIR ${BUILD_DIRECTORY})
set(LIB_DIR ${BUILD_DIR}/lib/Release)
set(LIB_FIX)
if (CMAKE_BUILD_TYPE MATCHES "Debug")set(LIB_DIR ${BUILD_DIR}/lib/Debug)set(LIB_FIX _d)
endif ()get_filename_component(ABSOLUTE_PATH ${LIB_DIR} ABSOLUTE)
set(LIB_DIR ${ABSOLUTE_PATH})set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_PDB_OUTPUT_DIRECTORY ${LIB_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIB_DIR})set(LIB_DIR_FIX ${LIB_DIR})
option(USE_VS_BUILD "use visual studio build." OFF)
if (USE_VS_BUILD)set(LIB_DIR_FIX ${LIB_DIR}/bin/Debug)
endif ()
#################### set include path ####################
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/source/cpp/logger${CMAKE_CURRENT_SOURCE_DIR}/source/cpp/misc${CMAKE_CURRENT_SOURCE_DIR}/source/cpp${BUILD_DIR}/include
)#################### scan source files ####################
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/cpp/logger SRC_FILES)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/cpp/misc SRC_FILES)
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/source/cpp SRC_FILES)#####设置资源文件
set(RESOURCE_SOURCESimage.qrc)
#################### version config ####################
if (MSVC)set(MY_VERSIONINFO_RC "${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc")configure_file("${CMAKE_CURRENT_SOURCE_DIR}/resource.rc.in""${MY_VERSIONINFO_RC}")
endif ()set(MY_VERSIONINFO_RC "")add_executable(${PROJECT_NAME} main.cpp mainwindow.cpp mainwindow.h mainwindow.ui ${SRC_FILES} ${RESOURCE_SOURCES} ${MY_VERSIONINFO_RC})#################### set target properties ####################
set_target_properties(${PROJECT_NAME} PROPERTIES DEBUG_POSTFIX _d)set_property(TARGET ${PROJECT_NAME} PROPERTY WIN32_EXECUTABLE true)#################### set target dependencies ####################
find_package(Qt${QT_VERSION} COMPONENTS ${REQUIRED_LIBS} REQUIRED)###############vcpkg的三方库######################################
find_package(g3log CONFIG REQUIRED)###############三方静态库#########################################
set(REDIS_CLIENT_LIB ${LIB_DIR_FIX}/redisclient${LIB_FIX}.lib)set(THIRD_LIBSg3log${REDIS_CLIENT_LIB})target_link_libraries(${PROJECT_NAME} PRIVATE ${REQUIRED_LIBS_QUALIFIED} ${THIRD_LIBS})
其他资源
【QT】QSS美化——基础知识_qt qss_Jason~shen的博客-CSDN博客
【Qt】使用Qss设置QPushButton图标和显示文本的位置-CSDN博客
https://www.cnblogs.com/csuftzzk/p/qss_button_menu.html
https://www.cnblogs.com/wangqiguo/p/4960776.html
https://www.cnblogs.com/bclshuai/p/9809679.html
CSS3 background-origin 属性 | 菜鸟教程
相关文章:
Qt界面美化之自定义qss样式表
原生的QT界面不好看,有时候需要根据美工的设计图修改样式。如果使用QML的话搞界面是快,但是QML有点儿吃内存,有时简单的功能还是用传统c的widget方便些。好在有qss,传统界面也可以美化的。QSS称为Qt Style Sheets也就是Qt样式表&a…...
春招进行时:“211文科硕士吐槽工资5500” HR:行情和能力决定价值
学历重要,还是能力重要? 春招进行时,不少学生求职遇冷,会把原因归结为学历水平不够高、毕业院校不够档次、专业不够热门、非一线城市就业机会少等等。 直到上海一位211大学的文科男硕士,吐槽招聘会提供的岗位薪资待遇…...
【DaVinci Developer专题】-45-自动生成SWC中所有Runnable对应的C文件
点击返回「Autosar从入门到精通-实战篇」总目录 案例背景(共5页精讲): 在DaVinci Developer中,以Test_A_SWC的Runnable为例,见图0-1。我们现在尝试自动生成一个包含Test_A_SWC_Init和Test_A_SWC_Main函数原型(也是适用于 C/S Port Serve Runnable)的C文件。 图0-1 目…...
redis启动和关闭服务脚本
编译安装redis,自己写了个脚本。 简单实现启动、关闭和 查看redis服务。 基本流程如下: 脚本执行,必须附带1个参数,没有参数会提示附带参数。 脚本会获取redis-server进程数量。作为开启、关闭以及查看redis服务的数据依据。 …...
windows CMD快捷键:
🐱个人主页:莎萌玩家🙋♂️作者简介:全栈领域新星创作者、专注于全栈各领域技术,共同学习共同进步,一起加油呀!💫系列专栏:网络爬虫、WEB全栈开发📢资料领取…...
【C/C++语言】刷题|双指针|数组|单链表
主页:114514的代码大冒 qq:2188956112(欢迎小伙伴呀hi✿(。◕ᴗ◕。)✿ ) Gitee:庄嘉豪 (zhuang-jiahaoxxx) - Gitee.com 文章目录 目录 文章目录 前言 一、删除有序数组中的重复项 二、合并两个有序数组 三,移除…...
Leetcode.1487 保证文件名唯一
题目链接 Leetcode.1487 保证文件名唯一 Rating : 1697 题目描述 给你一个长度为 n的字符串数组 names。你将会在文件系统中创建 n个文件夹:在第 i 分钟,新建名为 names[i]的文件夹。 由于两个文件 不能 共享相同的文件名,因此如…...
python-星号(*)-双星号(**)-函数动态参数匹配-解包操作
文章目录1.乘法和幂运算符2.函数接收数量不固定的入参3.限制函数入参仅以关键字形式输入4. 可迭代对象解包操作5.扩展可迭代对象解包1.乘法和幂运算符 ● 单个 * 用于乘法运算 ● 两个 ** 表示幂运算 >>> 2*3 >>> 6 >>> 2**3 >>> 82.函数…...
面试官:为什么说ArrayList线程不安全?
本博客知识点收录于:⭐️《JavaSE系列教程》⭐️ 1)线程安全与不安全集合 我们学习集合的时候发现集合存在由线程安全集合和线程不安全集合;线程安全效率低,安全性高;反之,线程不安全效率高,安…...
STP详解
STP STP全称为“生成树协议”(Spanning Tree Protocol),是一种网络协议,用于在交换机网络中防止网络回路产生,保证网络的稳定和可靠性。它通过在网络中选择一条主路径(树形结构),并…...
linux AWK常用命令 —— 筑梦之路
搜集整理awk常用命令,以便使用查询 # 打印文件第一列awk {print $1} rumenz.txt# 打印文件前两列awk {print $1,$2} rumenz.txt# 打印文件最后一列awk {print $NF} rumenz.txt# 打印文件总行数awk END{print NR} rumenz.txt# 打印文件第一行awk NR1{print} rumenz.…...
SpringCloud:服务拆分及远程调用
目录 SpringCloud:服务拆分及远程调用 1、服务拆分 2、远程调用 SpringCloud:服务拆分及远程调用 SpringCloud是目前国内使用最广泛的微服务框架。 官网地址: Spring Cloud SpringCloud集成了各种微服务功能组件,并基于SpringBoot实现了…...
网络应用之javascript函数定义和调用
函数定义和调用学习目标能够写出函数的定义和调用方式1. 函数定义函数就是可以重复使用的代码块, 使用关键字 function 定义函数。<script type"text/javascript">// 函数定义function fnAlert(){alert(hello!);} </script>2. 函数调用函数调用就是函数名…...
使用VNC远程连接Ubuntu - 内网穿透实现公网远程办公
写在前面:博主是一只经过实战开发历练后投身培训事业的“小山猪”,昵称取自动画片《狮子王》中的“彭彭”,总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域,如今终有小成…...
JavaScript Date 日期对象
文章目录JavaScript Date 日期对象Date 对象Date 对象属性Date 对象方法创建日期设置日期两个日期比较JavaScript Date 日期对象 日期对象用于处理日期和时间。 Date 对象 Date 对象用于处理日期与实际。 创建 Date 对象: new Date(). 以上四种方法同样可以创建…...
婴幼儿常见八大疾病及护理方法
在1岁之前,婴儿的体质还没有完全发育,很容易生病,大多数婴儿在1岁之后都会更好。今天,新的稀有婴儿育儿专家组织了一些婴儿最容易患的疾病和护理方法。1、新生儿黄疸宝宝出生后,你可能会注意到他的皮肤发黄。别担心&am…...
UVa 817 According to Bartjens 数字表达式 DFS ID 迭代加深搜 逆波兰表达式
题目链接:According to Bartjens 题目描述: 给定一个由数字和一个组成的字符串,你需要在数字之间添加,−,∗,-,*,−,∗三种符号,在保证表达式合法的情况下(同时形成的新的数字不能有前导零),使表…...
c++基础/类和对象
c基础 2.1名字空间 namespace 防止命名冲突 说明:名字空间可以在全局作用域或其他作用域(另一个名字空间)内部定义,但不能在函数或类的内部定义。 使用: #include<iostream> using namespace std; //std中包…...
2023年中国人工智能产业趋势报告
易观:尽管2022年人工智能市场发展活跃度不及预期,但2022年对人工智能产业来说无疑是令人激动的一年。年中由DALL-E 2以及其后Stable Diffusion和Midjourney等文本-图像生成模型引起公众对人工智能生成内容的大量关注,年末ChatGPT的横空出世刷…...
STM32定时器的配置,解析预分频系数和重装载值与时钟频率的关系
🎊【蓝桥杯嵌入式】专题正在持续更新中,原理图解析✨,各模块分析✨以及历年真题讲解✨都在这儿哦,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 - 蓝…...
HunyuanVideo-Foley与Java后端集成:构建高并发音效生成服务
HunyuanVideo-Foley与Java后端集成:构建高并发音效生成服务 1. 场景需求与技术挑战 在线教育平台面临一个共同痛点:海量视频课程需要配乐,但人工配乐成本高、效率低。一个中等规模的平台每月新增课程可能达到上万节,传统音乐制作…...
图像处理中的NCC算法:从原理到优化(附Python实现对比)
图像处理中的NCC算法:从原理到优化(附Python实现对比) 在计算机视觉领域,模板匹配是一项基础而重要的技术。想象一下这样的场景:你正在开发一个工业质检系统,需要在流水线上快速识别产品上的特定标识&#…...
USB批量传输中ZLP的必要性:为何512字节整数倍数据包会丢失
1. USB批量传输中的ZLP到底是什么? 第一次遇到USB批量传输丢数据的问题时,我也是一头雾水。明明发送端显示数据已经成功发送,接收端却死活收不到完整数据。后来排查发现,问题出在数据包大小刚好是512字节的整数倍时。这就是我们今…...
如何快速配置安卓虚拟摄像头VCAM:专业使用技巧完整指南
如何快速配置安卓虚拟摄像头VCAM:专业使用技巧完整指南 【免费下载链接】com.example.vcam 虚拟摄像头 virtual camera 项目地址: https://gitcode.com/gh_mirrors/co/com.example.vcam 安卓虚拟摄像头VCAM是一款基于Xposed框架的创新工具,能够将…...
告别盲目点优化!手把手教你用Zemax 2024构建‘先结构后像差’的高效优化工作流
告别盲目点优化!手把手教你用Zemax 2024构建‘先结构后像差’的高效优化工作流 在光学设计领域,Zemax作为行业标杆工具,其优化功能强大却也让许多设计师陷入"不断点击优化按钮"的困境。真正高效的设计不在于反复试错,而…...
Alt App Installer:打破微软商店限制的Windows应用自由安装方案
Alt App Installer:打破微软商店限制的Windows应用自由安装方案 【免费下载链接】alt-app-installer A Program To Download And Install Microsoft Store Apps Without Store 项目地址: https://gitcode.com/gh_mirrors/alt/alt-app-installer 你是否曾经因…...
Loop:让Mac窗口管理效率倍增的效率神器
Loop:让Mac窗口管理效率倍增的效率神器 【免费下载链接】Loop MacOS窗口管理 项目地址: https://gitcode.com/GitHub_Trending/lo/Loop 你是否也曾在多任务处理时,被杂乱无章的窗口搞得焦头烂额?切换应用时总要在一堆窗口中寻找目标&a…...
League-Toolkit:基于LCU API的英雄联盟本地化效率工具集
League-Toolkit:基于LCU API的英雄联盟本地化效率工具集 【免费下载链接】League-Toolkit 兴趣使然的、简单易用的英雄联盟工具集。支持战绩查询、自动秒选等功能。基于 LCU API。 项目地址: https://gitcode.com/gh_mirrors/le/League-Toolkit 在英雄联盟的…...
AI Agent驱动业务规则测试:从复杂逻辑到精准用例的自动化实践
1. AI Agent如何重塑业务规则测试 第一次接触AI Agent驱动的测试用例生成时,我正被一个保险理赔系统的测试工作折磨得焦头烂额。那套系统里有上百条复杂的业务规则,光是理解"投保人年龄超过60岁且保单满5年但未达10年时,赔付比例调整为8…...
使用Java实现数据的生产和消费
【Kafka】Java实现数据的生产和消费 Kafka介绍 Kafka 是由 LinkedIn 公司开发的,它是一个分布式的,支持多分区、多副本,基于 Zookeeper 的分布式消息流平台,它同时也是一款开源的基于发布订阅模式的消息引擎系统。 Kafka术语 …...
