Qt加载qml的方式

1、QQmlApplicationEngined搭配 Window
示例:

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}    

这种方式是加载以 Window为跟对象的 QML 文件,QML 拥有窗口的完整控制权,可以直接设置标题、窗口尺寸等属性。

 

2、QQuickView 搭配 Item
示例:

#include <QGuiApplication>
#include <QQuickView>
int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQuickView *view = new QQuickView;
    view->setResizeMode(QQuickView::SizeRootObjectToView);
    view->setSource(QUrl(QStringLiteral("qrc:/main.qml")));
    view->show();

    return app.exec();
}

使用 QQuickView 显示 QML 文件,对窗口的控制权(标题、窗口尺寸)是在 C++代码中,QML 文件是以 Item (及 以Item为根的组件)作为根对象。

 

3、QQuickWidget 加载 QML【Item】
示例:

QQuickWidget *view = new QQuickWidget;
view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
view->show();

QQuickWidget是继承于 QWidget 控件,这种方式主要是用于在 QWidget 界面上加载 QML 界面。

 参考:https://blog.csdn.net/luoyayun361/article/details/77113516/

 

PS:

所以只有第一种是对窗口有绝对的控制权;

后面两种的区别:

①、QQuickWidget的继承自QWidget,可以直接添加到Qt布局中;

②、QQuickView继承自QQuickWindow(继承自QWindow),通过转换才能添加到Qt布局中:

QQuickView *view = new QQuickView();
QWidget *widget = QWidget::createWindowContainer(view, this);
view->setSource(QUrl("qrc:/main.qml"));

③、QQuickWidget因涉及渲染到render到OpenGL帧缓冲区对象,会带来性能损失,导致较QQuickView性能稍低;

④、QQuickWidget将禁用所有平台上的线程render loop,例如Animator类和vsync驱动的动画不能使用;

⑤、避免在QQuickWidget上调用winId(),这个函数会触发本机窗口的创建,导致性能降低,并可能出现渲染问题;

故:

如主体项目为QWidget,QML只作为辅助,如完成一下显示小动画之类,那么请选择QQuickWidget,可以更方便得与已有项目中的QWidget结合;

如项目为全新,不涉及到QWidget的历史包袱,那么果断选择性能更好的QQuickView

 参考:https://blog.csdn.net/qq_37996632/article/details/113284468

 

4、QQmlEngine + QQmlComponent

#include <QApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQuickWindow>
#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QQmlEngine engine;
    QQmlComponent *component = new QQmlComponent(&engine);

    QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit()));

    component->loadUrl(QUrl("qrc:/main.qml"));

    if (!component->isReady() ) {
        qWarning("%s", qPrintable(component->errorString()));
        return -1;
    }

    QObject *topLevel = component->create();
    QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);

    QSurfaceFormat surfaceFormat = window->requestedFormat();
    window->setFormat(surfaceFormat);
    window->show();

    return app.exec();
}

这种方式大多数地方都没有写,个人感觉没必要使用。参考:https://blog.csdn.net/qq_34139994/article/details/105195447

posted @ 2021-11-26 09:01  朱小勇  阅读(1914)  评论(0编辑  收藏  举报