代码之家  ›  专栏  ›  技术社区  ›  jesperhh

在不手动标记要设置样式的每个属性的情况下设置QML样式

  •  20
  • jesperhh  · 技术社区  · 10 年前

    我知道QML不像小部件那样支持CSS样式,我已经阅读了样式/主题化的替代方法:

    这些方法的常见之处在于,它们要求开发人员指定QML中可以样式化的部分,方法是绑定到样式化QML文件/单例中的属性,或者使用Loader根据样式名加载不同的QML组件。我想要的是像CSS中的“id”选择器而不是“class”选择器那样工作的东西,这样各个QML文件就不必知道以后是否会设置样式。

    我当前的方法使所有QML文件看起来与此类似(使用链接2中的方法):

    主.qml

    Rectangle {
        Id: background
        color: g_theme.background.color 
        //g_theme is defined in root context and loaded dynamically
    }
    

    我想做的是:

    主.qml

    Rectangle {
        Id: background
        color: “green” // default color
    }
    

    然后有一个定义(或类似)

    Main.qml #background.color: red
    

    目前这是可能的吗,或者未来Qt版本中正在开发的东西,或者首选的样式方式是否会继续类似于上面链接中描述的方法?

    2 回复  |  直到 10 年前
        1
  •  18
  •   TheBootroo    10 年前

    首选的方法不是在默认组件上应用样式,而是从这些组件派生以创建预先设置样式的自定义组件。

    我为我的项目所做的工作:

    首先,我创建一个集中的“主题”文件,作为JavaScript共享模块:

    // MyTheme.js
    .pragma library;
    var bgColor   = "steelblue";
    var fgColor   = "darkred";
    var lineSize  = 2;
    var roundness = 6;
    

    接下来,我创建依赖它的自定义组件:

    // MyRoundedRect.qml
    import QtQuick 2.0;
    import "MyTheme.js" as Theme;
    Rectangle {
        color: Theme.bgColor;
        border {
            width: Theme.lineSize;
            color: Theme.fgColor;
        }
        radius: Theme.roundness;
    }
    

    然后,我可以用一行代码在任何地方使用我的预样式组件:

    MyRoundedRect { }
    

    这种方法有一个巨大的优点:它是真正面向对象的,而不是简单的蒙皮。

    如果您愿意,您甚至可以在自定义组件中添加嵌套对象,如文本、图像、阴影等,甚至可以添加一些UI逻辑,如鼠标悬停时的颜色更改。

    PS:是的,可以使用QML单例而不是JS模块,但它需要额外的 qmldir 文件,仅Qt 5.2支持,这可能是限制性的。显然,上下文属性中的C++QObject也可以工作(例如,如果您想从磁盘上的文件加载皮肤财产…)。

        2
  •  1
  •   Alexander Stepaniuk    9 年前

    看看 Qt Quick Controls Styles

    使用“控件样式”时,无需显式指定目标控件中的每个属性。所有财产都可以在单独的 [ControlName]Style 组件(例如。 ButtonStyle ).
    然后在目标组件中(例如。 Button )您只能在一行代码中引用样式组件。

    这里唯一的缺点是Style组件仅适用于Qt Quick Controls。不适用于任何Qt组件。