如何更新样式表的单个属性?

伊戈尔

我有一个窗户:

class MyWindow : public QWindow
{
.....
};

MyWindow *window;

以及一组样式表属性:

MyWindow
{
    style1: value1;
    style2: value2;
}

为了在窗口上设置这些属性,我必须调用:

window->setStyleSheet( "style1: value1" );
window->setStyleSheet( "style2: value2" );

例如设置a的对齐方式QPushButton需要设置text-align属性。

现在假设我要修改style1的value1值。我可以通过2种方式做到这一点:

  1. window->setStyleSheet( "style1: new-value" );

要么

  1. window->setStyleSheet( "style1: new-value; style2: value2" );

区别在于,在第二种情况下,我需要重建之前设置的整个样式表并追加更改。

现在的问题-就您所知,我绝对必须在方法2中设置任何窗口/样式吗?

为了更改1个属性值而不得不重建属性表当然很奇怪,但是我想问一下,以防万一。

斯科普恰诺夫

背景

为了在窗口上设置这些属性,我必须调用:

window->setStyleSheet( "style1: value1" );
window->setStyleSheet( "style2: value2" );

样式表是cascading,但不是累积的,这意味着后面的样式表将取消上一个样式表。

考虑以下示例:

auto *label = new QLabel("test", this);

label->setStyleSheet("background-color: yellow");
label->setStyleSheet("color: red");

结果是:文本为红色,但背景为默认颜色。

如果最后两行切换位置,则结果为:背景为黄色,但是文本现在具有默认颜色。

因此,关于何时绝对必须执行方法2的问题的答案是:

总是

考虑到这一背景,为了回答标题中的问题,我建议您采用以下解决方案:

  1. 将样式表转换为JSON
  2. 更新选择的价值
  3. 将JSON转换回样式表
  4. 将新样式表设置为小部件

提出的解决方案听起来可能很复杂,但是幸运的是,我准备了一个类StylesheetManipulator该类具有必要的功能以及如何使用它的示例:

StylesheetManipulator.h

#ifndef STYLESHEETMANIPULATOR_H
#define STYLESHEETMANIPULATOR_H

#include <qglobal.h>
#include <QJsonArray>

class StylesheetManipulator
{
public:
    static QString updateStylesheetProperty(const QString &styleSheet, const QString &selector, const QString &property, const QString &newValue);

private:
    static QJsonArray styleSheetToJson(const QString &styleSheet);
    static QJsonArray styleSheetPropertiesToJson(const QString &properties);
    static QJsonArray updateValue(const QString &selector, const QString &propertyName, const QString &newValue, const QJsonArray &jsonStyleSheet);
    static QString jsonToStyleSheet(const QJsonArray &jsonStyleSheet);
};

#endif // STYLESHEETMANIPULATOR_H

StylesheetManipulator.cpp

QString StylesheetManipulator::updateStylesheetProperty(const QString &styleSheet, const QString &selector, const QString &property, const QString &newValue)
{
    return jsonToStyleSheet(updateValue(selector, property, newValue, styleSheetToJson(styleSheet)));
}

QJsonArray StylesheetManipulator::styleSheetToJson(const QString &styleSheet)
{
    QJsonArray jsonStyleSheet;

    if (styleSheet.isEmpty())
        return jsonStyleSheet;

    foreach (const QString &style, styleSheet.trimmed().split("}")) {
        const QString &trimmedStyle(style.trimmed());

        if (!trimmedStyle.isEmpty()) {
            const QStringList &list(trimmedStyle.split("{"));

            jsonStyleSheet.append(QJsonObject {
                                 {"selector", list.first().trimmed()},
                                 {"properties", styleSheetPropertiesToJson(list.last())}
                             });
        }
    }

    return jsonStyleSheet;
}

QJsonArray StylesheetManipulator::styleSheetPropertiesToJson(const QString &properties)
{
    QJsonArray jsonProperties;

    if (properties.isEmpty())
        return jsonProperties;

    foreach (const QString &property, properties.trimmed().split(";")) {
        const QString &trimmedProperty(property.trimmed());

        if (!trimmedProperty.isEmpty()) {
            const QStringList &list(trimmedProperty.split(":"));

            jsonProperties.append(QJsonObject{
                                      {"name", list.first().trimmed()},
                                      {"value", list.last().trimmed()}
                                  });
        }
    }

    return jsonProperties;
}

QJsonArray StylesheetManipulator::updateValue(const QString &selector, const QString &propertyName, const QString &newValue, const QJsonArray &jsonStyleSheet)
{
    QJsonArray a;

    foreach (const QJsonValue &value, jsonStyleSheet) {
        const QJsonObject &currentStyle(value.toObject());
        const QString &currentSelector(currentStyle["selector"].toString());
        bool selectorFound = currentSelector == selector;
        QJsonArray properties;

        foreach (const QJsonValue &value, currentStyle["properties"].toArray()) {
            QJsonObject property(value.toObject());

            if (selectorFound && (property["name"].toString() == propertyName))
                property["value"] = newValue;

            properties.append(property);
        }

        a.append(QJsonObject{
                     {"selector", currentSelector},
                     {"properties", properties}
                 });
    }

    return a;
}

QString StylesheetManipulator::jsonToStyleSheet(const QJsonArray &jsonStyleSheet)
{
    QString styleSheet;

    foreach (const QJsonValue &value, jsonStyleSheet) {
        const QJsonObject &currentStyle(value.toObject());

        styleSheet.append(currentStyle["selector"].toString() + " {");

        foreach (const QJsonValue &value, currentStyle["properties"].toArray()) {
            QJsonObject property(value.toObject());

            styleSheet.append(" " + property["name"].toString() + ": " + property["value"].toString() + ";");
        }

        styleSheet.append(" } ");
    }

    return styleSheet;
}

MainWindow.cpp

MainWindow::MainWindow(QWidget *parent) :
    QWidget(parent)
{
    auto *label = new QLabel("test", this);
    auto *l = new QVBoxLayout(this);

    label->setStyleSheet("QFrame { background-color: yellow; border: 2px solid blue } QLabel { color: red; }");
    label->setStyleSheet(StylesheetManipulator::updateStylesheetProperty(label->styleSheet(), "QLabel", "color", "green"));

    l->addWidget(label);

    resize(300, 200);
}

该示例的完整代码可在GitHub找到

该示例产生以下结果:

带有蓝色边框包围的黄色背景上的绿色文本的窗口

请注意,尽管最初将文本颜色设置为红色(QLabel { color: red; }),但实际上已将其更改为绿色。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

使用React Native从样式表覆盖单个样式属性

来自分类Dev

使用属性样式表

来自分类Dev

如何在样式表中指定progressBarStyleHorizontal属性

来自分类Dev

如何更改样式表的src属性

来自分类Dev

Qt样式表中的属性组合

来自分类Dev

从样式表中提取 xml 属性

来自分类Dev

如何为单个xhtml文件添加动态CSS样式表

来自分类Dev

如何将CSS样式表应用于单个特定元素?

来自分类Dev

css 样式表作为组件参数/单个组件具有不同的样式表

来自分类Dev

如何从HTML解析/下载样式表

来自分类Dev

如何保持xml样式表?

来自分类Dev

如何修改导线样式表

来自分类Dev

如何应用范围样式表?

来自分类Dev

移动设备的样式表应如何?

来自分类Dev

如何覆盖全局Bootstrap样式表?

来自分类Dev

如何从样式表调用JBOSS服务?

来自分类Dev

如何为插件添加样式表

来自分类Dev

如何保持xml样式表?

来自分类Dev

如何从HTML解析/下载样式表

来自分类Dev

如何更改QMessageBox按钮的样式表?

来自分类Dev

如何应用范围样式表?

来自分类Dev

如何更改链接的样式表?

来自分类Dev

如何选择不带ID的样式表?

来自分类Dev

如何为带有属性的Xml嵌套节点编写样式表?

来自分类Dev

如何通过外部样式表而不是使用属性来控制图像的宽度/高度?

来自分类Dev

如何使用D3 JS设置样式表的属性?

来自分类Dev

如何使用样式表中的“ display:inline-block或block或inline”属性创建此布局?

来自分类Dev

如何将按钮的样式表设置为具有多个属性?

来自分类Dev

如何在 RTL 转换期间禁用以前样式表中的 CSS 属性?