【问题标题】:Styling QML without manually marking each property to be styled在不手动标记要设置样式的每个属性的情况下设置 QML 样式
【发布时间】:2014-11-09 03:31:41
【问题描述】:

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

这些方法的共同点是,它们要求开发人员指定可以设置样式的 QML 部分,方法是绑定到“样式化 QML 文件/单例”中的属性,或者使用加载器加载不同的基于样式名称的 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 版本准备中,或者首选的样式设置方式是否会继续类似于上面链接中描述的方法?

【问题讨论】:

    标签: css qt qml styling


    【解决方案1】:

    查看Qt Quick Controls Styles也可能会有所帮助

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

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

    【讨论】:

      【解决方案2】:

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

      我为我的项目做什么:

      首先,我创建一个集中的“主题”文件,作为 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 也可以工作(例如,如果您想从磁盘上的文件加载皮肤属性......)。

      【讨论】:

      • 感谢您的回答 - 我想您的方法与我们目前所做的类似,只是我们使用 qml 文件而不是 .js 文件来定义“主题”。我的问题是,我们必须尽早决定要设置样式的内容,以避免必须经历大量主题和控件并修改要应用样式的属性。但现在它工作正常,所以我们将继续使用这种方法,直到出现更好的结果。
      • 是否有可能摆脱import "MyTheme.js" as Theme; 声明?我想完全像@jesperhh 但使用外部二进制资源。我想知道是否可以在运行时更改主题而无需声明导入。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多