qt笔记之main.cpp加载qml文件的3种方法QQuickView 、QQmlApplicationEngine、QQuickWidget

发布于:2024-06-22 ⋅ 阅读:(240) ⋅ 点赞:(0)

qt笔记之main.cpp加载qml文件的3种方法QQuickView 、QQmlApplicationEngine、QQuickWidget

—— 2024-06-16 下午

code review!


时序和新旧顺序

  • Qt 5.0 引入 QQuickView
  • Qt 5.1 引入 QQmlApplicationEngine
  • Qt 5.3 引入 QQuickWidget

1.使用qtcreator创建qml空项目,默认使用QQmlApplicationEngine

创建项目后的出现的文件列表

user@user-vm:~/qt_cpp_test/qml_test$ ls
main.cpp  main.qml  qml.qrc  qml_test.pro

1.1.main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

1.2.qml

import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
}

1.3.qml_test.pro

QT += quick

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Refer to the documentation for the
# deprecated API to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
        main.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Additional import path used to resolve QML modules just for Qt Quick Designer
QML_DESIGNER_IMPORT_PATH =

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

1.4.qml.qrc

<RCC>
    <qresource prefix="/">
        <file>main.qml</file>
    </qresource>
</RCC>

2.QQuickViewQQmlApplicationEngine对比

在使用 Qt Creator 创建一个空的 QML 程序时,可以选择使用 QQuickViewQQmlApplicationEngine 来加载和显示 QML 文件。在 Qt Creator 中创建一个新的 Qt Quick 应用程序时,默认情况下并不会提供选项让选择使用 QQuickView 或 QQmlApplicationEngine。通常,创建的模板会使用 QQmlApplicationEngine,因为它是一个更通用和灵活的类,适用于大多数应用场景。

使用 QQuickView

QQuickView 是一个 QWindow 子类,用于创建一个独立窗口来显示 QML 内容。它更适用于纯 QML 应用程序或者需要单独窗口显示 QML 内容的应用。

QQuickView: 如果的应用程序主要使用 QML,或者需要一个独立窗口来显示 QML 内容,那么 QQuickView 更加适合。

  • 当使用 QQuickView 时,确保没有无意中创建第二个窗口。例如,不要在 QML 文件中再创建一个 Window 或 ApplicationWindow,因为 QQuickView 本身已经是一个窗口。
  • 如果在 QML 文件中使用 Window 或 ApplicationWindow,则会导致 QQuickView 运行时弹出两个窗口。因此,使用 QQuickView 时,应避免在 QML 文件中使用 Window 或 ApplicationWindow。

使用 QQmlApplicationEngine

QQmlApplicationEngine 是一个更加灵活的类,可用于加载和管理 QML 组件,并且可以结合 C++ 对象进行更复杂的逻辑处理。下面是一个使用 QQmlApplicationEngine 来加载 QML 文件的示例程序:

  • 当使用 QQmlApplicationEngine 时,QML 文件应该包含一个顶层窗口组件,例如 Window 或 ApplicationWindow,才能正确显示窗口。

对比与选择

  • QQuickView: 适用于需要创建一个独立窗口来显示 QML 内容的简单应用程序。它提供了一个简洁的方法来加载和显示 QML 文件。
  • QQmlApplicationEngine: 提供了更灵活的功能,适用于需要加载多个 QML 文件或需要更复杂的 C++ 与 QML 交互的应用程序。

通常,对于简单的 QML 应用程序,可以使用 QQuickView。对于复杂的项目,尤其是需要与 C++ 代码进行较多交互的项目,推荐使用 QQmlApplicationEngine

3.QQuickViewQQmlApplicationEngine进一步对比

以下是 QQuickViewQQmlApplicationEngine 的对比表格,特别关注它们在加载 QML 文件时的行为,以及是否会导致弹出两个窗口的情况。
在这里插入图片描述

在这里插入图片描述

特性 QQuickView QQmlApplicationEngine
主要用途 用于显示单个 QML 文件的视图组件 用于管理和加载整个 QML 应用程序
加载 QML 文件 view.setSource(QUrl("qrc:/main.qml")) engine.load(QUrl("qrc:/main.qml"))
顶层组件 不需要 WindowApplicationWindow 需要 WindowApplicationWindow
是否会弹出两个窗口 如果 QML 文件中包含 WindowApplicationWindow,则会弹出两个窗口 正常情况下不会弹出两个窗口,除非有多个顶层组件
配置窗口属性 通过 QQuickView 的方法直接配置 通过 QML 文件中的 WindowApplicationWindow 配置
示例代码加载 QML [见下文示例代码] [见下文示例代码]
适用场景 简单的 QML 界面显示 全功能的 QML 应用程序

使用 QQuickView 加载 QML 文件

C++ 代码:

#include <QGuiApplication>
#include <QQuickView>

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

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

    return app.exec();
}

QML 文件(main.qml):

import QtQuick 2.0

Rectangle {
    width: 640
    height: 480
    color: "lightblue"

    Text {
        text: "Hello, World!"
        anchors.centerIn: parent
    }
}

注意: 当使用 QQuickView 时,不要在 QML 文件中使用 WindowApplicationWindow 组件,否则会弹出两个窗口。

使用 QQmlApplicationEngine 加载 QML 文件

C++ 代码:

#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();
}

QML 文件(main.qml):

import QtQuick 2.0
import QtQuick.Window 1.0

Window {
    visible: true
    width: 640
    height: 480
    color: "lightblue"

    Text {
        text: "Hello, World!"
        anchors.centerIn: parent
    }
}

注意: 当使用 QQmlApplicationEngine 时,必须在 QML 文件中包含一个 WindowApplicationWindow 组件,否则即使加载成功也不会弹出窗口。

结论

  • QQuickView:适用于简单的单视图应用,确保 QML 文件没有 WindowApplicationWindow 组件,以避免弹出两个窗口。
  • QQmlApplicationEngine:适用于更复杂的 QML 应用,需要在 QML 文件中包含 WindowApplicationWindow 组件,确保正常显示窗口。

4.QQuickView 、QQmlApplicationEngine、QQuickWidget对比表格

特性 QQuickView QQmlApplicationEngine QQuickWidget
类型 QWindow 子类 无窗口类,管理 QML 组件 QWidget 子类
使用场景 独立窗口显示 QML 内容 复杂应用,加载多个 QML 文件,C++ 与 QML 交互 传统 QWidget 应用中嵌入 QML 内容
布局支持 不支持 QWidget 布局管理器 不适用 支持 QWidget 布局管理器
OpenGL 支持 使用 OpenGL 渲染 使用 OpenGL 渲染 默认使用 OpenGL 渲染(可禁用)
混合界面 适合纯 QML 应用或需要独立窗口的场景 适合复杂的 QML 应用和 C++ 交互 适合在现有 QWidget 应用中嵌入 QML 内容
加载 QML 文件 通过 setSource 方法 通过 load 方法 通过 setSource 方法
性能 较高性能,直接渲染到窗口 较高性能,直接管理 QML 组件 相对较低,需处理 QWidget 和 QML 之间的转换
错误处理 基本的错误处理 提供更详细的错误处理机制 基本的错误处理
渲染控制 完全控制 QML 内容的渲染 完全控制 QML 内容的渲染 需要处理 QWidget 和 QML 的渲染同步问题
跨平台支持
便捷性 简单易用,快速原型开发 灵活,适合复杂应用 便于在现有 QWidget 应用中集成 QML
C++ 与 QML 交互 支持,但不如 QQmlApplicationEngine 灵活 支持更复杂和灵活的交互 支持,但需要处理 QWidget 和 QML 的交互问题
窗口管理 独立窗口 无窗口管理 嵌入到现有 QWidget 界面中
适用项目类型 小型到中型项目,独立的 QML 应用 中型到大型项目,复杂的 QML 和 C++ 应用 需要在现有的 QWidget 应用中嵌入 QML 的项目

总结

  • QQuickView:

    • 适用于需要创建独立窗口来显示 QML 内容的应用。
    • 提供简单的接口和较高的性能,适合纯 QML 应用或需要快速原型开发的场景。
  • QQmlApplicationEngine:

    • 适用于复杂应用,尤其是需要加载多个 QML 文件和处理复杂 C++ 与 QML 交互的场景。
    • 提供更详细的错误处理机制和灵活性,适合中型到大型项目。
  • QQuickWidget:

    • 适用于需要在现有 QWidget 应用中嵌入 QML 内容的场景。
    • 支持 QWidget 布局管理器,但在性能上可能稍逊,需要处理 QWidget 和 QML 之间的渲染同步问题。

网站公告

今日签到

点亮在社区的每一天
去签到