我的应用程序同时使用c ++和QML。
我已经在C ++部分定义了几个对象来访问SQL等。
看起来像:
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = 0);
Q_INVOKABLE void someFunction(const QString &query);
};
qmlRegisterType<MyObject>("xxx.xxx", 1, 0, "MyObject");
理想情况下,我只需要在JML中使用这些对象,而不是在QML中。
我尝试了很多例子并阅读了所有文档,但仍无法解决我的问题。
所以我的问题:
var obj = Qt.createComponent("MyObject");
,但似乎不行。是否可以用正常的JS样式定义新对象 - var obj = new MyObject;
?TypeError: Property 'someFunction' of object QQmlComponent(0x3605f5c0) is not a function.
我在这里做错了什么?我的对象派生自QObject,而不是来自QQmlComponent。答案 0 :(得分:4)
您的对象不是Component
,但您可以改为使用Qt.createQmlObject
。
答案 1 :(得分:2)
文档很清楚,但混淆看起来像是在QML方面。这应该让你开始:
//C++
class MyObject : public QObject
{
Q_OBJECT
public:
MyObject(QObject *parent = 0);
Q_INVOKABLE void someFunction(const QString &query) { qDebug() << query;}
};
....
qmlRegisterType<MyObject>("foo.bar", 1, 0, "MyObject");
QML如下:
import foo.bar 1.0 //This is your register type
Item {
MyObject { //here's the instance, remember it is declarative
id: myObject;
}
MyObject {
id: myObjectInstance2
}
Button {
onClicked: {
myObject.someFunction("doSomething"); //here is using a reference
myObjectInstance2.someFunction("doSomethingElse");
}
}
}
点击后你应该看到输出中的字符串(我没有编译或测试它)。请务必在主类中注册类型。
如果您在移动设备上使用SQL,则应该检查本地存储对象。这是一个非常简单的回调API,适用于SQLite。我将它用于桌面应用程序,并没有太多麻烦。返回列表有点烦人,所以只需坚持使用简单类型即可轻松实现JavaScript集成。
我希望有所帮助。我非常喜欢在QML中工作,一旦你学会了它就会非常有趣(足够熟练工作1-2周)。
答案 2 :(得分:2)
您可以使用
QQmlApplicationEngine engine;
engine.globalObject().setProperty("CppCreator", engine.newQObject(&CppCreator::GetInstance()));
CppCreator是一个用于创建其他c ++对象的QObject
Q_INVOKABLE QObject* Create(const QString& type_name);
然后你可以在qml js中创建c ++对象,比如
var test = CppCreator.Create("Your Type");
这不完美,但满足了我的要求。希望它可以帮到你。
答案 3 :(得分:0)
这是一个有想象的// Factory class
class Creator : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE QObject* createObject(const QString& typeName, const QVariantMap& arguments);
};
QObject* Creator::createObject(const QString& typeName, const QVariantMap& arguments)
{
if (typeName == "TextFile")
{
QString filePath = arguments.value("filePath").toString();
TextFile::OpenMode openMode =
qvariant_cast<TextFile::OpenMode>(arguments.value("openMode", TextFile::ReadWrite));
QString codec = arguments.value("codec", "UTF-8").toString();
return new TextFile(qmlEngine(this), filePath, openMode, codec);
}
Q_ASSERT(false);
return nullptr;
}
类的例子。首先,我们需要一个已建议的工厂类:
TextFile
注意:这个类比必要的要复杂一些。它应该创建多种类型。现在我们已经有了工厂类,我们需要告诉QML / QJSEngine在调用 QJSValue creator = engine.newQObject(new Creator());
engine.globalObject().setProperty("_creator", creator);
engine.evaluate("function TextFile(path, mode) { return _creator.createObject(\"TextFile\", { filePath: path, openMode: mode }); }");
的new运算符时该怎么做。
TextFile
现在我们可以根据需要实现我们的var myFile = new TextFile("/path/to/file", TextFile.ReadWrite);
,即使是参数:
<aside id="appNav" class="fixed-top">
<div id="appNavTop" class="appHide">
<div class="container">
<div class="row">
<div class="col-12">
<span>appNavTop</span>
</div>
</div>
</div>
</div>
[...]
</aside>
.appHide {
height: 0 !important;
overflow: hidden
}
#appNavTop {
-webkit-transition-property: height;
transition-property: height;
height: 40px
}
$(window).on('scroll', function () {
if ($(document).scrollTop() > 0) {
$('#appNavTop').removeAttr('class');
} else {
$('#appNavTop').addClass('appHide');
}
});
致信this answer的作者。