如果不是 QML SystemPalette,QML 默认按钮快速控件从哪里获取颜色?
Posted
技术标签:
【中文标题】如果不是 QML SystemPalette,QML 默认按钮快速控件从哪里获取颜色?【英文标题】:Where does the QML default Button quick control get its colors from, if not QML SystemPalette? 【发布时间】:2016-11-06 20:45:30 【问题描述】:我使用的是 Windows 10 桌面系统。我想知道为什么我在 QML SystemPalette 中找不到颜色,而我看到 QML 默认按钮快速控件正在使用这些颜色。
按钮出现在我面前
#e1e1e2 正常 #e4f0f9 突出显示 #cce4f7 按下但我在活动/非活动/禁用的 SystemPalette 部分中找不到任何这些。在 SystemPalette 中,“按钮”颜色是#f0f0f0,更接近的是使用#e3e3e3 的“中光”,唯一的蓝色部分是使用#0078d7 的“高光”。
它们是否以某种方式混合在一起?
更新:
可能缺少重要的信息:我正在使用 QtQuick.Controls 1.4 中的按钮。
如果我看一下 2.0 中的那个,它也不会显示 SystemPalette 中的颜色 - 但由于没有为 Qt Quick Controls 2 预先构建的原生样式,这可能无法预料?
更新:
澄清一下。这更像是一个出于好奇的问题。这里没有严重的问题。我只是想知道 QML SystemPalette 中是否存在错误,甚至怀疑它的用处。它是不是很正确的常数的累积?
【问题讨论】:
你的意思是Qt Quick Controls 2中的默认样式吗? 我正在使用 QtQuick.Controls 1.4,但尝试版本 2 后问题仍然存在。更新了问题... 好的,那么对于 Qt Quick Controls 1,您使用的是哪种风格?您是在 main() 中创建 QApplication 还是 QGuiApplication?它是哪个版本的 Windows? 这是 Windows 10。我还没有实例化 QApplication 或 QGuiApplication(但会使用后者)。到目前为止,我只是在 ApplicationWindow 下将仅在 qmlscene 中运行的东西放在一起。 如果应用程序使用QApplication
,那么版本 1 QtQuick.Controls 元素将使用原生样式,即尽可能看起来原生。这就是@jpnurmi 问的原因。您肯定是在实例化 QApplication
或其基类 QGuiApplication
否则您的程序根本不会显示任何内容
【参考方案1】:
我和你有同样的问题,不幸的是,我好奇地深入研究了源代码,看看他们是如何做到的。 对于其他有同样问题的人来说,很难创建自己的控件,并且具有与内置控件相同的风格灵活性。即使您费心(我也有),它也不容易分发,因为您必须在运行时针对命名空间注册 QML 文件。最后,更容易不打扰任何这些,只需像人们在其他所有 GUI 框架中所做的那样上传控件的副本。 整个过程的文档记录很差,特别是对于那些想要以 .QML 文件开始和结束的人来说。
从他们的 ToolBar.qml 实现中获取一个 sn-p:
import QtQuick.Templates 2.2 as T
import QtQuick.Controls.Material 2.2
//...
background: Rectangle
implicitHeight: 48
color: control.Material.toolBarColor
//...
简而言之,他们实现了每个默认控件三个不同的时间,并根据 QQuickStyle 的特定设置在它们之间切换。
总之,在 qquickstyle.cpp 中可以找到,楼下的大部分内容都在 QQuickStyleSpec::Resolve() 函数中。如果您选择将样式设置为内置选项之一,这会将 QQuickStyleSpec::style 字符串设置为安装目录中的文件夹。一个示例文件夹路径可能是: C:\Qt\5.9\mingw53_32\qml\QtQuick\Controls.2 为“默认”,或 C:\Qt\5.9\mingw53_32\qml\QtQuick\Controls.2\Material 为“材料”。
这个路径最终被传递给 QtQuickControls2Plugin::registerTypes(),其中 QQuickStyleSelector.select() 将相对路径转换为绝对路径,并对我们要注册的 QML 文件执行分支搜索。有了绝对路径、uri (QtQuick.Controls) 和我们想要的任何版本号,我们现在可以像这样在 uri 下注册 QML 文件:
qmlRegisterType(QUrl("file:///C:/absolute/file/path/FancyControl.qml"), "QtQuick.Controls", 2, 1, "FancyControl");
为方便起见,我将函数调用分解为常量字面量,以便您确切知道发生了什么。请注意,实际上不可能在“QtQuick.Controls”下注册,因为该函数声称特定的命名空间已经注册。不管那是什么意思。
这一切都发生在运行时,这使得分发这样的东西变得更加困难——你必须编写一个库来简化注册。
我想他们这样做的原因是因为每种风格都有很大的不同。材料设计要复杂得多,需要使用 OpenGL 着色器,以及其他特定于材料设计的其他设置。因此,要提供一种具有完全不同底层内容的多种样式是一个控件的错觉,他们必须别无选择,只能使用 .QML 文件来玩弹珠机。对简单界面的一种扭曲。
我的建议是忘记任何这些存在并分发您的控件的最低有效副本,就像人们在其他所有 GUI 框架中所做的那样。
【讨论】:
当您说“创建您自己的控件,并具有与内置控件相同的风格灵活性”时,您到底想做什么?关于文档很差,如果有反馈可以准确描述您认为应该改进的地方,那就太好了:bugreports.qt.io 在撰写本文时,我试图弄清楚如何创建一个可以适应所选样式的控件——Material、Universal 或 Default——根据需要,因为使用了任何技术可能对通用控制设计有用。当我说文档在这方面很差时,我的意思是说,虽然注册 QML 文件名称空间的函数有一些文档,但没有任何方法可以将它们捆绑在一起。如果没有逆向工程,我不可能弄清楚如何做到这一点,因为 Style 文档没有谈论这个。以上是关于如果不是 QML SystemPalette,QML 默认按钮快速控件从哪里获取颜色?的主要内容,如果未能解决你的问题,请参考以下文章
在QT / QML中是否有IOS的visibleMapRect?