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



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

  • https://qt-project.org/wiki/QmlStyling
  • http://www.slideshare.net/BurkhardStubert/practical-qml-key-navigation/34

这些方法的共同点是,它们要求开发人员指定QML中可以设置样式的部分,方法是绑定到"设置QML文件/单例样式"中的属性,或者使用Loader根据样式名称加载不同的QML组件。我想要的是类似CSS中的"id"选择器而不是"class"选择器的东西,这样单个QML文件就不必知道它们以后是否会被设置样式。

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

Main.qml

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

我想做的是:

Main.qml

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

然后有一个定义(或类似)的样式文件

Main.qml #background.color: red

目前这可能吗,或者未来Qt版本正在酝酿中,或者首选的造型方式会继续类似于上面链接中描述的方法吗?

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

我为我的项目做什么:

首先,我创建了一个集中的"主题"文件,作为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 singleton而不是JS模块,但它需要额外的qmldir文件,并且只有Qt 5.2才支持,这可能是有限制的。显然,上下文属性中的C++QObject也可以工作(例如,如果你想从磁盘上的文件加载皮肤属性…)

查看Qt快速控制样式也会有所帮助

使用控件样式时,不必显式指定目标控件中的每个特性。所有属性都可以在单独的[ControlName]Style组件(例如ButtonStyle)中定义
然后在目标组件(例如Button)中,您可以在一行代码中引用样式组件。

这里唯一的缺点是样式组件仅可用于Qt快速控制。不适用于任何Qt组件。

最新更新