В моем проекте есть два модуля, один состоит исключительно из файлов qml, а второй - из файлов C++, из которых я пытаюсь выставить класс и использовать его в первом модуле. Структура немного сложна, поэтому я воспроизвел проблему с помощью более простого тестового проекта. Я заметил, что QML не может распознать ни одноэлементный тип, ни не-одноэлементный тип.
Проект имеет следующую структуру:
Код: Выделить всё
│ CMakeLists.txt
│ main.cpp
│
└───logicmodule
CMakeLists.txt
Main.qml
Message.h
MySingleton.h
Код: Выделить всё
// logicmodule/MySingleton.h
#pragma once
#include
#include
#include
class MySingleton : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
MySingleton(QObject *parent = nullptr)
: QObject{parent}
{}
public slots:
QString exec(const QString &str) { return "somestring"; }
};
Код: Выделить всё
// logicmodule/Message.h
#pragma once
#include
#include
#include
class Message : public QObject
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(QString author MEMBER m_author NOTIFY authorChanged)
public:
Message() {}
signals:
void authorChanged();
private:
QString m_author;
};
Код: Выделить всё
// logicmodule/Main.qml
import QtQuick
import QtQuick.Controls
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
// property Message msg: Message {}
Button {
id: button
anchors.centerIn: parent
text: "Click me"
onClicked: {
label.text = MySingleton.exec(label.text)
}
}
Label {
id: label
anchors.top: button.bottom
}
}
Код: Выделить всё
// logicmodule/CMakeLists.txt
project(logicmodule VERSION 0.1 LANGUAGES CXX)
qt_add_library(${PROJECT_NAME} STATIC)
qt6_add_qml_module(${PROJECT_NAME}
URI Main
VERSION 1.0
NO_PLUGIN
RESOURCE_PREFIX "/qt/qml"
QML_FILES
Main.qml
SOURCES
MySingleton.h
Message.h
)
target_link_libraries(${PROJECT_NAME} PUBLIC
Qt6::Core
Qt6::Gui
Qt6::Qml
Qt6::Quick
)
target_include_directories(${PROJECT_NAME}
PUBLIC
.
)
Код: Выделить всё
// main.cpp
#include
#include
#include "Message.h"
#include "MySingleton.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(u"qrc:/qt/qml/Main/Main.qml"_qs);
QObject::connect(
&engine,
&QQmlApplicationEngine::objectCreated,
&app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
},
Qt::QueuedConnection);
engine.addImportPath(QCoreApplication::applicationDirPath() + "/qml");
engine.addImportPath(":/");
engine.load(url);
if (engine.rootObjects().isEmpty()) {
return -1;
}
return app.exec();
}
Код: Выделить всё
// CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(typetest VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 6.5 REQUIRED COMPONENTS Quick)
set(QT_QML_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/qml)
qt_standard_project_setup(REQUIRES 6.5)
add_subdirectory(logicmodule)
qt_add_executable(apptypetest
main.cpp
)
target_link_libraries(apptypetest PUBLIC
logicmodule
)
# No effect
# target_include_directories(apptypetest
# PUBLIC
# "${PROJECT_SOURCE_DIR}/logicmodule"
# logicmodule
# )
# include_directories(logicmodule)
Код: Выделить всё
qrc:/qt/qml/Main/Main.qml:16: ReferenceError: MySingleton is not defined
qmltyperegistration include path не подтверждает подкаталоги
Но файлы с пользовательскими типами, похоже, включаются без каких-либо префиксов.
Я также заметил, что в папке сборки у меня есть файл build\Debug\logicmodule\logicmodule_qmltyperegistrations .cpp и он содержит вызовы qmlRegisterTypesAndRevisions, но кажется, что это не имеет эффекта?
Также попробовал структуру проекта без каких-либо дополнительных библиотек (поэтому без логического модуля lib, все находится в корне проекта, и у меня есть только один CMakeLists), и он, похоже, работает нормально, и все пользовательские типы распознаются QML.
Могло бы кто-нибудь укажет мне, что я делаю не так с библиотекой? Почему QML не может распознать тип, если он определен внутри библиотеки?
Подробнее здесь: https://stackoverflow.com/questions/786 ... e-qml-file