【问题标题】:Inherit color palettes in QML在 QML 中继承调色板
【发布时间】:2026-01-10 21:35:01
【问题描述】:

我想在 QML 中创建一个非常简单的调色板,如下所示:

QtObject {
  property color foreground
  property color background
  property color primary
  property color secondary
}

然后我希望能够为组件设置调色板并让该组件的所有(自定义)子控件自动继承调色板。要么到组件树的底部,要么直到我在其中一个孩子上设置另一个调色板。

+ root (Palette A)
+- child (inherit Palette A)
+-- child (inherit Palette A)
+- child (Palette B)
+-- child (inherit Palette B)

这有可能吗?

编辑:我目前考虑的方法是在root 组件中创建一个colorPalette 属性并从child 组件中引用它。每当我想覆盖当前调色板时,我只需将colorPalette 属性添加到child。 这当然可行,但我认为这不是一个非常干净的解决方案,因为那样我只能在存在全局 colorPalette 属性时使用我的组件。此外,这可能会导致以后的命名冲突。

【问题讨论】:

  • 你已经做了什么?你遇到了哪些问题?请注意,SO 不是学习资源。
  • 感谢提醒,我编辑了我的帖子。
  • 请张贴Minimal, Complete, and Verifiable example,而不是描述代码。

标签: qt qml


【解决方案1】:

好吧,考虑到任何根元素的属性都将通过动态范围直接或不直接对所有嵌套元素可见,除非它们被遮蔽,否则实现您想要的应该不难。

您需要做的就是仔细命名您的属性,以免它们被遮蔽。从那时起,如果您执行someprop: somevalue,它将尝试找到somevalue 并将其解析为它找到的第一个。

如果 QML 有这样的接口和多重继承,那就太好了,不幸的是,没有任何甚至宏支持来避免随之而来的过度复制粘贴和相关的维护问题。

如果您要使用嵌套方法,我建议您使用Item 而不是QtObject,因为后者不能真正有孩子。嵌套方法最终会导致开销,因为每次要在其中嵌套某些内容时都必须拥有一个调色板实例。

另一种解决方案是使用QtObject 属性,这样您就可以将它的多个实例分配给单个调色板对象。但是,您还必须手动为每个应该提供调色板的对象实现该属性,并且每次要引用颜色时,您都必须执行 palette.colorValue 而不仅仅是 colorValue 并且没有调色板属性,只是调色板嵌套适配器。这并不是说嵌套方法会不那么冗长,因为它很可能会遇到使用嵌套项的布局问题,这也需要代码来解决。

【讨论】:

  • 感谢您的建议。我现在选择使用动态范围方法。不过,我希望有一个更清洁的解决方案,当colorPalette 未定义时不会失败。
  • @JohannesStricker 您可以通过检查它是否未定义来进行故障保护。
  • 是的,我知道。如果我必须在很多地方检查它,这很快就会变得混乱。也许我可以做类似property ColorPalette _colorPalette: colorPalette || ColorPalette{}.