Qt5.11中QtQuickControls1 Menu样式仅在QtWidgets QApplication下生效
问题背景
开发环境为Windows系统 + Qt 5.11.0,受硬件限制无法升级Qt版本,开发嵌入式应用时遇到如下异常:
- 应用入口实例化为
QGuiApplication时,Qt Quick Controls 1模块提供的QML Menu组件无法识别配置的style属性,自定义样式不生效;替换为QtWidgets模块的QApplication实例后,Menu自定义样式可正常加载。 - 默认样式存在差异:
QApplication默认加载Desktop样式,QGuiApplication默认使用Base样式,且无法加载Desktop样式。
待解答疑问
- 正常加载Qt Quick Controls 1模块的样式是否必须依赖QtWidgets模块?是否存在遗漏的配置项?
QApplication实例为何会改变QML组件的样式加载逻辑?
复现代码
main.cpp
#include <QtQml/qqmlapplicationengine.h> #include <QtQml/qqmlcomponent.h> #include <QtWidgets/QApplication> int main(int argc, char ** argv) { //QGuiApplication* app = new QApplication(argc, argv); // 样式正常生效 QGuiApplication* app = new QGuiApplication(argc, argv); // 自定义样式不生效 QQmlApplicationEngine engine; engine.load(QUrl("file:///C:/main.qml")); app->exec(); delete app; return 0; }
main.qml
import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 Window { visible: true Column{ CheckBox { text: "checkbox"} ComboBox { model: ["combobox"] } Button { text: "button"} Button { text: "custom" menu: Menu { style: MenuStyle { frame: Rectangle { color: "yellow" } } MenuItem{text: "menuitem"} } } } }
运行现象
- 预期结果:Menu组件背景色为黄色。
- 实际结果:Menu自定义样式未生效。
问题解答
疑问1解答
Qt Quick Controls 1的Desktop样式、Menu等弹出类组件的自定义样式加载逻辑确实强依赖QtWidgets模块,不存在遗漏的配置项。
Qt Quick Controls 1在设计时做了两套样式后端:
- 无QtWidgets依赖时,仅加载纯QML实现的Base样式,所有弹出类组件(Menu、ComboBox下拉面板等)完全基于Qt Quick场景图渲染,这套后端没有实现Menu组件的自定义style属性解析逻辑,因此配置的样式不会生效。
- 检测到QtWidgets模块加载且应用实例为
QApplication时,会自动注册Desktop样式后端,弹出类组件的渲染会接入QtWidgets的样式体系,此时自定义的MenuStyle等配置才会被正确解析。
若硬件资源允许,即使不使用任何QWidget类,只要在项目中链接QtWidgets模块、实例化
QApplication即可解决样式问题,QtWidgets的额外资源开销在绝大多数嵌入式硬件上可接受。Qt 5.11版本没有提供脱离QtWidgets加载Qt Quick Controls 1自定义Menu样式的官方接口。
疑问2解答
QApplication是QGuiApplication的子类,初始化时会额外执行QtWidgets模块的平台样式注册、原生控件钩子挂载逻辑,直接改变Qt Quick Controls 1的样式加载流程:
QApplication初始化阶段会自动将Qt Quick Controls 1的全局样式设置为Desktop样式,替换QGuiApplication默认加载的纯QML Base样式。- Desktop样式后端重写了Menu、ComboBox等弹出组件的创建逻辑,将弹出层的渲染接管到QtWidgets的样式体系中,用户在QML中配置的style属性会被该后端读取并生效。
- 纯
QGuiApplication环境下,QtWidgets模块的初始化钩子不会触发,Qt Quick Controls 1只会加载无Widgets依赖的Base样式后端,因此无法识别Menu组件上配置的自定义样式。
内容的提问来源于stack exchange,提问作者Jack White
相关产品推荐
相关产品推荐

