如何使用 qmlRegisterType 在 QML 中指定 c++ 类型?
Posted
技术标签:
【中文标题】如何使用 qmlRegisterType 在 QML 中指定 c++ 类型?【英文标题】:how can I specify a c++ type in QML using qmlRegisterType? 【发布时间】:2019-05-13 13:16:20 【问题描述】:我需要在 c++ 中使用 qmlRegisterType 来使用 QML 定义一个公共类型。这应该很简单,但我在 QML 中有一个错误。 这是c++。
QGuiApplication app(ai_argc, aipp_argv);
qmlRegisterType<MiniModel>("miniModel", 1, 0, "MiniModel");//there it is !
QQmlApplicationEngine engine;
engine.addImportPath(QStringLiteral("..\\..\\..\\..\\Tools\\Qt\\5.12.0\\x64\\5.12.0\\msvc2017_64\\qml"));
engine.load(QUrl(QStringLiteral("../../Inc/miniModel/miniModel.qml")));
return app.exec();
这是 QML
import QtQuick 2.5
import QtQuick.Window 2.5
import QtQuick.controls 2.5
import "..\\..\\x64\\Debug\\" miniModel 1.0 MiniModel//unknown component
ApplicationWindow
id: root
width: 300
height: 480
visible: true
property bool value: Minimodelqml.
BackEnd
id: backend
TextField
text: backend.userName
placeholderText: qsTr("User name")
anchors.centerIn: parent
onTextChanged: backend.userName = text
我试过了:
/*cpp*/qmlRegisterType<MiniModel>("miniModel", 1, 0, "MiniModel");
/*qml*/import miniModel 1.0 MiniModel //QML module not found
/*cpp*/qmlRegisterType<MiniModel>("anothertry.miniModel", 1, 0, "MiniModel");
/*cml*/import anothertry.miniModel 1.0//qml module not found
还有其他一些...我是 QMl 的新手,不知道如何处理它。
我没有使用 QtCreator 项目。这是一个视觉工作室 2017 解决方案。也许问题来自那里?
编辑:使用单例的代码工作“很好”
【问题讨论】:
项目结构如何?所有代码都在同一个构建对象中吗?最后两次尝试应该可以工作 不,所有内容都在单独的文件夹中。 TEST_VIEW4 包含一个 QML 文件夹,其中包含此 QML 代码的特定文件夹。它包含一个带有 exe 文件和批处理启动器的 bin 文件夹、一个带有标题的包含文件夹、一个带有源文件和 moc 文件 (cpp) 的源文件夹。和另一个包含 obj 文件的文件夹。稍后,用于通信的类将存储在 dll 中 这是非常令人震惊的engine.load(QUrl(QStringLiteral("../../Inc/miniModel/miniModel.qml")));
使用qrc:/
如下@mohabouje 的回答中所述。这可能会导致查找模块时出现问题。
尝试向engine.addImportPath
添加另一个调用,它指向您的 qml 所在的文件夹。如果可行,您可能需要检查 qml 是否实际编译到项目中(qrc 还需要一些编译操作,也许你错过了?)
我添加了 engine.addImportpath 并没有改变。我对 qrc 有点迷茫。不是 QtCreator 制作的指定文件夹架构的文件吗?因为我使用的是 Visual Studio,而不是 QtCreator。
【参考方案1】:
.qml
中的 import miniModel 1.0
应该可以工作
/*cpp*/qmlRegisterType<MiniModel>("miniModel", 1, 0, "MiniModel");
/*qml*/import miniModel 1.0
【讨论】:
这正是重点。它不是。对不起,我忘了告诉你在做这些奇怪的方法之前我尝试了正确的方法...... @QuentinGirault 尝试一个更简单的项目,你一定在做一些奇怪的事情。 /*我做了(我的解决方案中的一个新项目,不是太简单,而是更简单)并在这里发布了结果。我在主题中添加了它,我尝试的最后一个简单代码是关于单例的代码。我错过了 qmlRegistertype 我们必须在 QML 中实例化对象。我没有,也不能这样做*/【参考方案2】:这些是我将 C++ 类公开给 QML 引擎的一些常见步骤。
让我们从声明一些常量开始:
struct package_manager
static constexpr auto package_name = "com.mohabouje.package";
static constexpr auto package_version_major = 0;
static constexpr auto package_version_minor = 1;
然后创建您的 Qt 对象,并将属性公开给QML engine:
class MyObject : public QObject
Q_OBJECT
Q_PROPERTY(double awesome READ awesome WRITE setAwesome NOTIFY awesomeChanged)
public:
// ...
double awesome();
void setAwesome(double);
signals:
void awesomeChanged(double);
;
在你的主要,然后做:
int main(int argc, char* argv[])
QApplication app(argc, argv);
qmlRegisterType<MyObject>(package_manager::package_name,
package_manager::package_version_major,
package_manager::package_version_minor, "MyObject");
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
你的main.qml
变成:
import com.mohabouje.pacakge 0.1
ApplicationWindow
id: root
width: 300
height: 480
visible: true
Component.onCompleted:
MyObject
awesome: 25
查看tutorial了解更多详情。
【讨论】:
非常感谢,但我的问题是我坚持第一步。当我调用“import The.Exact.Thing.Written 1.0”时,QML 告诉我“找不到 QML 模块 (The.Exact.Thing.Written)。【参考方案3】:刚才有类似的问题,原来我的错误是我在QQuickView.setSource()
之后调用了qmlRegisterType()
【讨论】:
以上是关于如何使用 qmlRegisterType 在 QML 中指定 c++ 类型?的主要内容,如果未能解决你的问题,请参考以下文章
我需要整合我的 c++ 代码和 qml。但是我在使用 qmlRegisterType 时遇到了许多错误“未定义对‘Middlemen::staticMetaObject’的引用”