qt - 带有在运行时加载的自定义 QML 插件的基于 CMake 的项目仅在 MinGW 下失败

标签 qt plugins cmake qml mingw

我正在尝试使用 CMake 和 Qt 5.15.1 试验一个包含在运行时加载的虚拟自定义 QML 插件的小型项目。

项目结构

|-- CMakeLists.txt
|-- main.cpp
|-- main.qml
|-- main.qrc
|-- qmlplugins/
    |-- customqml/
        |-- CMakeLists.txt
        |-- customqml_plugin.cpp
        |-- customqml_plugin.h
        |-- customqml.cpp
        |-- customqml.h
        |-- qmldir

./CMakeLists.txt

cmake_minimum_required(VERSION 3.1)
project(test_qml_plugin LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 11)
set(CXX_STANDARD_REQUIRED ON)

find_package(Qt5 REQUIRED Gui Core Qml Quick)

add_subdirectory(qmlplugins/customqml)

add_executable(${PROJECT_NAME} main.cpp main.qrc)
target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Quick Qt5::Gui Qt5::Qml Qt5::Core)
add_dependencies(${PROJECT_NAME} customqml)
set_target_properties(${PROJECT_NAME} PROPERTIES AUTORCC ON)

./main.cpp

#include <QCoreApplication>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QUrl>
#include <QDir>

int main(int argc, char **argv) {
  QGuiApplication app(argc, argv);
  QQmlApplicationEngine engine;
  engine.addImportPath(QCoreApplication::applicationDirPath() + QDir::separator() + "qmlplugins");
  engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
  if (engine.rootObjects().isEmpty()) return -1;
  return app.exec();
}

./main.qml

import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.5

import customqml 1.0

ApplicationWindow {
  id: root
  title: qsTr("test_qml_plugin")
  width: 640
  height: 480
  visible: true

  CustomQml {}
}

./main.qrc

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

./qmlplugins/customqml/CMakeLists.txt

set(QMLDIR_SRC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/qmldir)
set(QMLDIR_BIN_PATH ${CMAKE_CURRENT_BINARY_DIR}/qmldir)
add_custom_target(customqml-qmldir DEPENDS ${QMLDIR_SRC_PATH} ${QMLDIR_BIN_PATH})
add_custom_command(
  COMMENT "Moving updated resource-file ${QMLDIR_SRC_PATH}"
  OUTPUT ${QMLDIR_BIN_PATH}
  DEPENDS ${QMLDIR_SRC_PATH}
  COMMAND ${CMAKE_COMMAND} -E copy_if_different ${QMLDIR_SRC_PATH} ${QMLDIR_BIN_PATH}
)

add_library(customqml MODULE customqml_plugin.cpp customqml.cpp)
target_link_libraries(customqml PRIVATE Qt5::Qml Qt5::Core)
add_dependencies(customqml customqml-qmldir)
set_target_properties(customqml PROPERTIES AUTOMOC ON)

./qmlplugins/customqml/customqml_plugin.cpp

#include "customqml_plugin.h"
#include "customqml.h"

#include <qqml.h>

void CustomqmlPlugin::registerTypes(const char *uri) {
  qmlRegisterType<FileIO>(uri, 1, 0, "CustomQml");
}

./qmlplugins/customqml/customqml_plugin.h

#pragma once

#include <QQmlExtensionPlugin>

class CustomqmlPlugin: public QQmlExtensionPlugin {
  Q_OBJECT
  Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)

public:
  void registerTypes(const char *uri) override;
};

./qmlplugins/customqml/customqml.cpp

#include "customqml.h"

CustomQml::CustomQml(QObject *parent): QObject(parent) {}

CustomQml::~CustomQml() {}

./qmlplugins/customqml/customqml.h

#pragma once

#include <QtCore>

class CustomQml: public QObject {
  Q_OBJECT
  Q_DISABLE_COPY(CustomQml)

public:
  CustomQml(QObject *parent = 0);
  ~CustomQml();
};

./qmlplugins/customqml/qmldir

module customqml
plugin customqml

我已经在 Windows 上使用 Visual Studio 2019 和 MinGW 8.0 gcc 10.2.0 进行了测试,还在 Ubuntu 上使用 gcc 9.3.0 进行了测试。

它使用所有这些配置构建时没有错误。

在运行时:

  • 使用 Visual Studio 和 Ubuntu 上的 gcc,应用程序运行没有任何问题并显示一个空窗口。
  • 但是对于 MinGW,它在运行时失败,engine.rootObjects() 是空的,我不明白为什么。我缺少什么?

最佳答案

如果包含 qrc 文件,则需要添加 set(CMAKE_AUTORCC ON)

关于qt - 带有在运行时加载的自定义 QML 插件的基于 CMake 的项目仅在 MinGW 下失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64417429/

相关文章:

qt - 如何使用 URL 路径作为文件名进行下载?

javascript - http ://responsive-nav. com/在 Android 上变得不稳定的动画

c++ - 在 fedora 27 中构建 glfw 时链接期间出错

c++ - QCPItemLine 正在自动绘制

c++ - 为什么使用 QQuickWindow::grabWindow() 会导致窗口变成图像?

c++ - C++ 中 QVariants 的使用和 QML 中的属性

c++ - 用 C++ 编写可移植动态加载库的最简单方法是什么?

eclipse - 如何以编程方式从完整类名中查找 Eclipse 插件中的 .java 文件?

CMake:在同级库的 add_library 上找不到源文件

CMake:如何将 INTERFACE_INCLUDE_DIRECTORIES 与 ExternalProject 一起使用?