从 C++ 代码创建单独的 QML 窗口

Posted

技术标签:

【中文标题】从 C++ 代码创建单独的 QML 窗口【英文标题】:Create separate QML window from C++ code 【发布时间】:2016-02-01 10:08:36 【问题描述】:

在我的应用程序中,我想用 C++ 代码创建另一个带有 QML UI 的窗口。

我知道可以使用 QML Window 类型创建另一个窗口,但我需要 C++ 代码中的相同内容。

到目前为止,我设法将我的附加 qml 文件加载到 QQmlComponent:

QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(QUrl(QStringLiteral("qrc:/testqml.qml")));
if ( component.isReady() )
    component.create();
else
    qWarning() << component.errorString();

如何在单独的窗口中显示?

【问题讨论】:

【参考方案1】:

您可以使用单个QQmlEngine 来实现这一点。按照您的代码,您可以执行以下操作:

QQmlEngine engine;
QQmlComponent component(&engine);
component.loadUrl(QUrl(QStringLiteral("qrc:/main.qml")));

if ( component.isReady() )
    component.create();
else
    qWarning() << component.errorString();

component.loadUrl(QUrl(QStringLiteral("qrc:/main2.qml")));

if ( component.isReady() )
    component.create();
else
    qWarning() << component.errorString();

我更喜欢QQmlApplicationEngine。这个类结合了QQmlEngineQQmlComponent 来提供一种方便的方式来加载单个QML 文件。所以如果你有机会使用QQmlApplicationEngine,你的代码行数会更少。

例子:

QGuiApplication app(argc, argv);

QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
engine.load(QUrl(QStringLiteral("qrc:/main2.qml")));

return app.exec();

我们也可以使用QQuickViewQQuickView 仅支持加载从 QQuickItem 派生的根对象,因此在这种情况下,我们的 qml 文件不能以 QML 类型 ApplicationWindowWindow 开头,就像上面的示例一样。所以在这种情况下,我们的main 可能是这样的:

QGuiApplication app(argc, argv);

QQuickView view;
view.setSource(QUrl("qrc:/main.qml"));
view.show();

QQuickView view2;
view2.setSource(QUrl("qrc:/main2.qml"));
view2.show();

return app.exec();

【讨论】:

感谢您的回答。因此,如果我使用“Window”或“ApplicationWindow”QML 类型作为我的 QML 的根元素,我假设第二种解决方案将起作用。我对么?我想这是我没有意识到的——我想我应该以某种方式从 C++ 创建窗口。现在我明白了 QML 支配一切。 你是对的 :) QQmlApplicationEngine 不会自动创建根窗口。阅读您的消息后,我认为用另一个选项更新我的答案是个好主意:使用QQuickView。如您所知,在这种情况下,QQuickView 仅支持加载从QQuickItem 派生的根对象。 由于某种原因,您使用一个 QQmlApplicationEngine 和两个加载文件的解决方案对我不起作用,第二个窗口只是拒绝显示。也许这是我的代码中的一些错误。无论如何,我找到了解决这个问题的更好方法(就我而言),将其作为另一个答案发布。无论如何感谢您的帮助! 很遗憾听到这个消息:(太棒了!:)【参考方案2】:

你可以尝试新建QQmlEngine

【讨论】:

【参考方案3】:

对于任何好奇的人,我最终用稍微不同的方法解决了这个问题。

我的 QML 根文档现在如下所示:

import QtQuick 2.4

Item 
    MyMainWindow 
        visible: true
    

    MyAuxiliaryWindow 
        visible: true
    

其中MainWindow 是具有根元素ApplicationWindow 的QML 组件,AuxiliaryWindow 是具有根元素Window 的组件。

工作得很好,您不必担心加载两个单独的 QML 文件。

【讨论】:

以上是关于从 C++ 代码创建单独的 QML 窗口的主要内容,如果未能解决你的问题,请参考以下文章

如何使用组件范围实例层次结构从 C++ 创建 QML 组件

qml 和 c++ 与 qt quick 2 应用程序

如何在 QML 中动态创建 Popup

如何创建 QQuickItem 的单独副本并将其呈现在不同的窗口上

Qt Quick - 如何仅通过 c++ 代码与 qml 属性交互

使用QML创建界面(转)