Qss自定义属性
QSS自定义属性
更多精彩内容 |
---|
👉个人内容分类汇总 👈 |
👉QSS样式学习 👈 |
文章目录
- QSS自定义属性
-
- @[toc]
- 前言
- 一、实现效果
- 二、使用方式
-
- 1.QSS设置Q_PROPERTY属性样式
- 2.QSS设置动态属性样式
- 3.qproperty-<属性名称>语法1
- 4.qproperty-<属性名称>语法2
- 四、主要代码
- 五、源代码
文章目录
- QSS自定义属性
-
- @[toc]
- 前言
- 一、实现效果
- 二、使用方式
-
- 1.QSS设置Q_PROPERTY属性样式
- 2.QSS设置动态属性样式
- 3.qproperty-<属性名称>语法1
- 4.qproperty-<属性名称>语法2
- 四、主要代码
- 五、源代码
前言
- Qss内置了许多的伪状态可以用于设置控件的样式动态变化(例如:
:checked
、:hover
),但在日常开发中为了更加灵活的样式,这些伪状态就不够用了;- 将QObject中的属性功能与Qss结合使用就会发现不一样的风景,主要有4种用法;
- 使用Qss属性选择器设置通过【Q_PROPERTY】定义的属性的样式,当属性状态改变后控件样式跟着改变;
- 使用Qss属性选择器设置通过【setProperty()】定义的动态属性的样式,当属性状态改变后控件样式跟着改变;
- 使用 【qproperty-<属性名称>】语法设置通过Q_PROPERTY定义的属性的值;
- 定义一个枚举,使用Q_ENUM或者Q_ENUMS注册枚举类型,使用Q_PROPERTY定义一个已注册的枚举类型的属性,可以通过【qproperty-<属性名称>:枚举名称】方式设置属性的值。
- 在代码中不再是将样式表放在资源文件中,而是放到可执行程序路径下,可定制性更强。
一、实现效果
二、使用方式
1.QSS设置Q_PROPERTY属性样式
-
在继承于QWidget的类中Q_OBJECT后,私有区域使用Q_PROPERTY定义一个属性;
Q_PROPERTY(bool checked READ isChecked WRITE setChecked)
-
在类中分别定义属性对应的变量、函数;
-
使用QSS属性选择器设置对应的样式,[属性名=属性值]
/* 设置Q_PROPERTY定义的属性样式 */ #Widget[checked = true] {background-color: rgb(0, 255, 127); }
-
在程序中修改属性值后,样式不会发生变化,需要调用polish(控件) 刷新控件样式;
this->style()->polish(this);
2.QSS设置动态属性样式
-
再Qss样式表中使用QSS属性选择器设置对应的样式,[属性名=属性值]
/* 设置动态属性样式 */ #Widget[property1 = true] {background-color: rgb(255, 0, 127); }
-
再程序中调用setProperty() 函数设置属性值,如果没有通过Q_PROPERTY定义属性,使用setProperty(“property1”, value)设置后会将property1添加为动态属性,并且返回false
this->setProperty("property1", value)
-
在程序中修改动态属性值后,样式不会发生变化,需要调用polish(控件) 刷新控件样式;
this->style()->polish(this);
3.qproperty-<属性名称>语法1
-
在继承于QWidget的类中Q_OBJECT后,私有区域使用Q_PROPERTY定义一个属性;
Q_PROPERTY(QColor BgColor READ isBgColor WRITE setBgColor)
-
在类中分别定义属性对应的变量、函数;
-
在Qss样式表中使用 qproperty-<属性名称>语法设置属性的值。
/* 通过Qss设置Q_PROPERTY定义的属性的值 */ #Widget {qproperty-BgColor: rgb(255, 0, 0); }
-
由于在程序界面还没显示时样式表还没生效,所以在构造函数中时无法获取设置后的属性值,在程序启动并且显示后可以获取设置后的属性值。
4.qproperty-<属性名称>语法2
-
在继承于QWidget的类中,公有区域定义一个枚举,并使用Q_ENUM或者Q_ENUMS向元对象系统注册枚举类型;
-
使用Q_PROPERTY定义一个该枚举类型的属性;
Q_PROPERTY(AgeEnum age READ age WRITE setAge)
-
在类中分别定义属性对应的变量、函数;
-
在Qss样式表中使用 qproperty-<属性名称>语法设置属性的值,值为注册的枚举中的项,不能是数字。
/* 通过Qss设置Q_PROPERTY定义的属性的值 */ #Widget {qproperty-age: age3; /* 通过Q_ENUM注册的枚举修改自定义属性值*/ }
-
在程序启动并且显示后可获取设置后的属性值;
四、主要代码
-
widget.h
#ifndef WIDGET_H #define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTQ_PROPERTY(bool checked READ isChecked WRITE setChecked)Q_PROPERTY(QColor BgColor READ isBgColor WRITE setBgColor)Q_PROPERTY(AgeEnum age READ age WRITE setAge) // 想要通过Q_ENUM注册的枚举修改属性值,属性的类型就需要时【枚举的类型】,而不能是其它类型,例如intpublic:Widget(QWidget *parent = nullptr);~Widget();enum AgeEnum {age1 = 10,age2 = 20,age3 = 30};Q_ENUM(AgeEnum) // 向元对象系统注册枚举类型(可以使用Q_ENUM或者Q_ENUMS,不过后者已经过时)bool isChecked() const;void setChecked(bool value);QColor isBgColor() const;void setBgColor(QColor color);AgeEnum age() const;void setAge(AgeEnum value);private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();private:void initStyle();private:Ui::Widget *ui;bool m_checked = false;QColor m_bgColor = QColor(255, 255, 255);AgeEnum m_age; }; #endif // WIDGET_H
-
widget.cpp
#include "widget.h" #include "ui_widget.h"#include <QFile> #include <QTextStream> #include <QDebug> #include <QStyle>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);initStyle();qDebug() << "在构造函数中获取属性值:" << m_bgColor.name(); // 无法获取到qss修改后的属性值 }Widget::~Widget() {delete ui; }bool Widget::isChecked() const {return m_checked; }void Widget::setChecked(bool value) {m_checked = value; }QColor Widget::isBgColor() const {return m_bgColor; }void Widget::setBgColor(QColor color) {m_bgColor = color; }Widget::AgeEnum Widget::age() const {return m_age; }void Widget::setAge(AgeEnum value) {m_age = value; }/* @brief 加载qss文件*/ void Widget::initStyle() {QString strFile = qApp->applicationDirPath() + "/style.css"; // 这里我没有使用资源文件,而是把样式表文件放在当前路径下,便于随时更换QFile file(strFile);if(file.open(QIODevice::ReadOnly)){QTextStream stream(&file);QString strQss;while (!stream.atEnd()){strQss.append(stream.readLine());}qApp->setStyleSheet(strQss); // 设置整个程序的样式表而不是当前窗口}else{qWarning() << "打开qss文件失败!";} }/* @brief 通过Q_PROPERTY定义的属性更新Qss样式* 设置属性的方式有两种* 方式一:setChecked* 方式二:setProperty("checked", value) : 设置成功返回true,否则返回false*/ void Widget::on_pushButton_clicked() {this->setChecked(!this->isChecked()); // 更改控件的属性 【Q_PROPERTY】this->style()->polish(this); // 属性值更改后重新初始化给定控件的样式。 }/* @brief 通过动态属性的方式更新QSS样式* 如果没有通过Q_PROPERTY定义属性,使用setProperty("property1", value)* 设置后会将property1添加为动态属性,并且返回false,* 效果和使用Q_PROPERTY定义的属性类似*/ void Widget::on_pushButton_2_clicked() {static bool value = true;qDebug() << this->setProperty("property1", value); // 设置动态属性value = !value;this->style()->polish(this); // 属性值更改后重新初始化给定控件的样式。 }/* @brief 在Qss通过qproperty-属性 的方式修改属性的值,qproperty 语法只在程序启动显示控件是生效一次* 在构造函数中由于控件还没有开始显示,所以qproperty没生效,是无法获取修改后的属性值的,在窗口显示后就可以获取到属性值* 注意:虽然主要继承于QObject的类都可以通过Q_PROPERTY定义属性,但是只有继承于QWidget的类定义的属性可以通过Qss修改,* 因为QObject不包含QStyle*/ void Widget::on_pushButton_3_clicked() {qDebug() << "程序启动后获取属性值:" << m_bgColor.name();qDebug() <<"Qss设置的属性值:" << m_age; }
-
style.css
/* 设置Q_PROPERTY定义的属性样式 */ #Widget[checked = true] {background-color: rgb(0, 255, 127); }/* 设置动态属性样式 */ #Widget[property1 = true] {background-color: rgb(255, 0, 127); }/* 通过Qss设置Q_PROPERTY定义的属性的值 */ #Widget {qproperty-BgColor: rgb(255, 0, 0);qproperty-age: age3; /* 通过Q_ENUM注册的枚举修改自定义属性值*/ }
五、源代码
- github
- gitee