Qss自定义属性

news2024/9/28 1:22:35

QSS自定义属性

更多精彩内容
👉个人内容分类汇总 👈
👉QSS样式学习 👈

文章目录

  • QSS自定义属性
    • @[toc]
  • 前言
  • 一、实现效果
  • 二、使用方式
    • 1.QSS设置Q_PROPERTY属性样式
    • 2.QSS设置动态属性样式
    • 3.qproperty-<属性名称>语法1
    • 4.qproperty-<属性名称>语法2
  • 四、主要代码
  • 五、源代码

前言

  • Qss内置了许多的伪状态可以用于设置控件的样式动态变化(例如::checked:hover),但在日常开发中为了更加灵活的样式,这些伪状态就不够用了;
  • 将QObject中的属性功能与Qss结合使用就会发现不一样的风景,主要有4种用法;
    1. 使用Qss属性选择器设置通过【Q_PROPERTY】定义的属性的样式,当属性状态改变后控件样式跟着改变;
    2. 使用Qss属性选择器设置通过【setProperty()】定义的动态属性的样式,当属性状态改变后控件样式跟着改变;
    3. 使用 【qproperty-<属性名称>】语法设置通过Q_PROPERTY定义的属性的值;
    4. 定义一个枚举,使用Q_ENUM或者Q_ENUMS注册枚举类型,使用Q_PROPERTY定义一个已注册的枚举类型的属性,可以通过【qproperty-<属性名称>:枚举名称】方式设置属性的值。
  • 在代码中不再是将样式表放在资源文件中,而是放到可执行程序路径下,可定制性更强。

一、实现效果

在这里插入图片描述

二、使用方式

1.QSS设置Q_PROPERTY属性样式

  1. 在继承于QWidget的类中Q_OBJECT后,私有区域使用Q_PROPERTY定义一个属性;

    Q_PROPERTY(bool checked READ isChecked WRITE setChecked)
    
  2. 在类中分别定义属性对应的变量、函数;

    在这里插入图片描述

  3. 使用QSS属性选择器设置对应的样式,[属性名=属性值]

    /* 设置Q_PROPERTY定义的属性样式 */
    #Widget[checked = true] {
        background-color: rgb(0, 255, 127);
    }
    
  4. 在程序中修改属性值后,样式不会发生变化,需要调用polish(控件) 刷新控件样式;

    this->style()->polish(this);
    

2.QSS设置动态属性样式

  1. 再Qss样式表中使用QSS属性选择器设置对应的样式,[属性名=属性值]

    /* 设置动态属性样式 */
    #Widget[property1 = true] {
        background-color: rgb(255, 0, 127);
    }
    
  2. 再程序中调用setProperty() 函数设置属性值,如果没有通过Q_PROPERTY定义属性,使用setProperty(“property1”, value)设置后会将property1添加为动态属性,并且返回false

    this->setProperty("property1", value)
    
  3. 在程序中修改动态属性值后,样式不会发生变化,需要调用polish(控件) 刷新控件样式;

    this->style()->polish(this); 
    

3.qproperty-<属性名称>语法1

  1. 在继承于QWidget的类中Q_OBJECT后,私有区域使用Q_PROPERTY定义一个属性;

    Q_PROPERTY(QColor BgColor READ isBgColor WRITE setBgColor)
    
  2. 在类中分别定义属性对应的变量、函数;

    在这里插入图片描述

  3. 在Qss样式表中使用 qproperty-<属性名称>语法设置属性的值。

    /* 通过Qss设置Q_PROPERTY定义的属性的值 */
    #Widget {
        qproperty-BgColor: rgb(255, 0, 0);
    }
    
  4. 由于在程序界面还没显示时样式表还没生效,所以在构造函数中时无法获取设置后的属性值,在程序启动并且显示后可以获取设置后的属性值。

    在这里插入图片描述

4.qproperty-<属性名称>语法2

  1. 在继承于QWidget的类中,公有区域定义一个枚举,并使用Q_ENUM或者Q_ENUMS向元对象系统注册枚举类型;

    在这里插入图片描述

  2. 使用Q_PROPERTY定义一个该枚举类型的属性;

    Q_PROPERTY(AgeEnum age READ age WRITE setAge)
    
  3. 在类中分别定义属性对应的变量、函数;

    在这里插入图片描述

  4. 在Qss样式表中使用 qproperty-<属性名称>语法设置属性的值,值为注册的枚举中的项,不能是数字。

    /* 通过Qss设置Q_PROPERTY定义的属性的值 */
    #Widget {
        qproperty-age: age3;                 /* 通过Q_ENUM注册的枚举修改自定义属性值*/
    }
    
  5. 在程序启动并且显示后可获取设置后的属性值;

    在这里插入图片描述

四、主要代码

  • widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QWidget>
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class Widget; }
    QT_END_NAMESPACE
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
        Q_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注册的枚举修改属性值,属性的类型就需要时【枚举的类型】,而不能是其它类型,例如int
    
    public:
        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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/375888.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在报表生成工具 Stimulsoft 中自定义报告查看器?

Stimulsoft Reports 是一款报告编写器&#xff0c;主要用于在桌面和Web上从头开始创建任何复杂的报告。可以在大多数平台上轻松实现部署&#xff0c;如ASP.NET, WinForms, .NET Core, JavaScript, WPF, Angular, Blazor, PHP, Java等&#xff0c;在你的应用程序中嵌入报告设计器…

华为OD机试模拟题 用 C++ 实现 - 猜字谜(2023.Q1)

最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明猜字谜题目输入输出描述备注示例一输入输出示例二输入输出思路Code使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,

IDEA配置 External Tool

有一些文件无法使用IDEA自带的工具打开&#xff0c;这时候就需要借助电脑上安装的第三方软件协助打开。比如使用电脑上安装的Notepad打开项目中的*.ppm文件。 一、配置External Tool 参数说明&#xff1a; 名称(Name)&#xff1a;将在IntelliJ IDEA界面&#xff08;“ 工具”菜…

什么是api接口?(基本介绍)

API:应用程序接口(API:Application Program Interface) 应用程序接口是一组定义、程序及协议的集合&#xff0c;通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过调用 API 函数对应用程序进行开发&#xff0c;可以减轻编程任务。 …

ROS1/2机器人操作系统与时间Time的不解之缘

时间对于机器人操作系统非常重要。所有机器人类的编程中所涉及的变量如果需要在网络中传输都需要这个数据结构的时间戳。宏观上&#xff0c;ROS1、ROS2各版本都有官方支持的时间节点。ROS时钟--支持时间倒计时小工具效果如下&#xff1a;如果要部署机器人操作系统&#xff0c;R…

IP路由原理、静态路由及动态路由区分

1、什么是路由? 路由器 在互联网中进行路由选择所使用的设备&#xff0c;或者说&#xff0c;实现路由的设备&#xff0c;我们称之为路由器。 路由器关键功能&#xff1a;检查数据包的目的地确定信息源发现可能的路由选择最佳路由验证和维护路由信息 什么是路由 路由是指导I…

洗地机什么牌子最好?洗地机品牌排行榜前十名

洗地机是近年来火热的清洁电器&#xff0c;凭借强劲的顽渍污渍去除和高效的地面清洁性能&#xff0c;成为了保持洁净家居环境、为生活做减法的黑科技&#xff0c;颇受生活达人们的追捧和青睐。洗地机的品牌、种类众多&#xff0c;一时间令人眼花缭乱。今天&#xff0c;我想为大…

fastadmin:在新增页面,打开弹窗单选,参数回传

样式&#xff1a;核心代码&#xff1a;一、弹窗的控制器中&#xff1a;// 定义一个公共函数select()&#xff0c;如果这个请求是Ajax&#xff0c;则返回index()函数&#xff0c;否则返回view对象的fetch()函数。 public function select() {if ($this->request->isAjax(…

C 学习笔记 —— 函数指针

函数指针 上面的第二个char (* f) (int);写法就是函数指针的声明&#xff1b; 首先&#xff0c;什么是函数指针&#xff1f;假设有一个指向 int类型变量的指针&#xff0c;该指针储存着这个int类型变量储存在内存位置的地址。 同样&#xff0c;函数也有地址&#xff0c;因为函…

LC-3—MIO、MMIO、Caller Save、Callee Save

LC-3—MIO、MMIOMMIOMIOCaller Save、Callee Save举个例子MMIO MMIO&#xff08;Memory Mapped I/O&#xff09;是一种在系统内存中映射I/O端口的技术&#xff0c;它允许设备直接访问内存中的特定地址&#xff0c;从而实现I/O操作。MMIO技术可以提高I/O操作的效率&#xff0c;…

Mysql 事务版本链(RR 与 RC 的本质区别)

版本链其实就是CURD的历史记录&#xff0c;回滚的本质也是用版本链中的最近一条历史记录覆盖当前记录。版本链针对的是每个表中的记录&#xff0c;只要表中有任意一条记录被修改&#xff0c;版本链中就会新增一条历史记录。 目录 1、为什么需要版本链&#xff1f; 2、有关版本…

《爆肝整理》保姆级系列教程python接口自动化(二十四)--unittest断言——中(详解)

简介 上一篇通过简单的案例给小伙伴们介绍了一下unittest断言&#xff0c;这篇我们将通过结合和围绕实际的工作来进行unittest的断言。这里以获取城市天气预报的接口为例&#xff0c;设计了 2 个用例&#xff0c;一个是查询北京的天气&#xff0c;一个是查询 南京为例&#xf…

接口幂等性的通用解决方案golang版

文章目录简介幂等性如何实现前端应当处理后端基于 token redis 处理简介 接口的幂等性是指&#xff1a; 用户对同一个操作发起多次请求&#xff0c;系统的设计需要保证其多次请求后结果是一致的。常见的如支付场景&#xff0c;连续快速点击两次支付 10 元&#xff0c;不应该扣…

阶段八:服务框架高级(第三章:分布式缓存Redis)

阶段八&#xff1a;服务框架高级&#xff08;第三章&#xff1a;分布式缓存Redis&#xff09;Day-分布式缓存Redis0.学习目标1.Redis持久化1.1.RDB持久化 【重要】1.1.1.执行时机1.1.2.RDB原理1.1.3.小结1.2.AOF持久化【重要】1.2.1.AOF原理1.2.2.AOF配置1.2.3.AOF文件重写1.3.…

搜广推 WideDeep 与 DeepCrossNetwork (DCN) - 记忆+泛化共存

😄 这节来讲讲Wide&Deep与Deep&CrossNetwork (DCN)。从下图可看出WD非常重要,后面衍生出了一堆WD的变体。本节要讲的WD和DCN结构都非常简单,但其设计思想值得学习。 🚀 wide&deep:2016年,谷歌提出。 🚀 Deep&CrossNetwork (DCN):2017年,谷歌和斯坦…

刷题小抄1-2数之和

时间复杂度和空间复杂度 对于一个算法高效性的评估,分为时间复杂度与空间复杂度两种,在算法优化到极致的情况下,只能舍弃时间来换取空间,或者舍弃空间来换取时间,故而两者可以说是互斥关系 时间复杂度衡量的是算法运行的速度,而空间复杂度衡量的是算法运行所需要的额外内存空…

【Ap AutoSAR入门与实战开发03】-【Ap_s2s模块02】:到底什么是基于信号,什么是基于服务,两者的主要区别是什么?

总目录链接==>> AutoSAR入门和实战系列总目录 文章目录 1 基于信号的通信2 基于服务的通信3 面向服务设计举例在【Ap_s2s模块01】中我们大概讲述了,为什么要有s2s模块,并且简单的阐述了基于信号的通信和基于SOME/IP的服务的通信,我们接下来详细分析一下这两个概念。…

Torch单独层赋值

20230227 - 引言 对于torch中的权值初始化方式&#xff0c;以往都是采用默认的方式&#xff0c;或者利用初始化库里面的函数。但是如果想尝试一些自己的想法&#xff0c;那就必须自己来填充这部分数据&#xff0c;例如看到的内容&#xff0c;利用PCA的公式来对权值进行填充。…

CSGO社区服务器搭建架设服务器配置以及环境准备

CSGO社区服务器搭建架设服务器配置以及环境准备 CSGO作为一款射击动作游戏还原场景真实性广受大批玩家的热爱&#xff0c;很多小伙伴也有想过自己搭建的话需要知道那些东西。 我是艾西&#xff0c;今天跟大家聊聊搭建架设前我们需要知道的事情&#xff1a; Windows&#xff1…

【谷歌grc】recaptcha browser-error 错误

grc 谷歌人机验证错误 https://www.google.com/recaptcha/api/siteverif 返回错误信息 browser-error [{"success": false,"error-codes": ["browser-error"] }]之前都是调通能用的&#xff0c;突然之间就不能用了&#xff0c;查了半天也没有找…