How to create and use C ++ objects in QML Javascript

My application uses both C ++ and QML.

I have defined several objects in C ++ for accessing SQL, etc.

Looks like:

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"); 

Ideally, I need to use these objects only in Javascript and not in QML.

I tried many examples and read all the documentation, but still can not solve my problem.

So my questions are:

  • How can I specify in Javascript an object defined in C ++? I tried var obj = Qt.createComponent("MyObject"); but it doesn't seem to work. Is it possible to define a new object in the usual JS style - var obj = new MyObject; ?
  • How can I access this created object in javascript? I tried obj.someFunction ("xxx"), but got some error - TypeError: Property 'someFunction' of object QQmlComponent(0x3605f5c0) is not a function. What am I doing wrong here? My object is derived from a QObject, not a QQmlComponent.
+7
javascript qt5 qml qt-quick qtquick2
source share
4 answers

Your object is not Component , but you can use Qt.createQmlObject .

+2
source share

The documentation is pretty straightforward, but the confusion looks as if it is on the side of the QML equation. This should start:

 //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 below:

 import foo.bar 1.0 //This is your register type Item { MyObject { //here the instance, remember it is declarative id: myObject; } MyObject { id: myObjectInstance2 } Button { onClicked: { myObject.someFunction("doSomething"); //here is using a reference myObjectInstance2.someFunction("doSomethingElse"); } } } 

When you click, you should see the lines in the output (I have not compiled and tested this). Be sure to register the type in your main class.

You should check the local repository object if you are using SQL on a mobile device. This is a pretty simple callback API that works with SQLite. I use it for desktop applications and have no particular problems. Return lists are a little annoying, so just try to stick with simple types for easy JavaScript integration.

Hope this helps. I really enjoy working in QML, it's pretty fun when you learn it (1-2 weeks to be experienced enough to work).

+1
source share

you can use

 QQmlApplicationEngine engine; engine.globalObject().setProperty("CppCreator", engine.newQObject(&CppCreator::GetInstance())); 

CppCreator is a QObject to create another C ++ object

 Q_INVOKABLE QObject* Create(const QString& type_name); 

Then you can create a C ++ object in qml js like

 var test = CppCreator.Create("Your Type"); 

It is not perfect, but it satisfied my demand. Hope this helps you.

+1
source share

Here is an example with a suggested TextFile class. First of all, we need a factory class, as already suggested:

 // 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; } 

Note. This class is a little more complicated than necessary. It is supposed to create several types. Now that we have the factory class, we need to tell QML / QJSEngine what to do if you call the new operator on the TextFile .

  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 }); }"); 

Now we can customize our TextFile as desired, even with options:

 var myFile = new TextFile("/path/to/file", TextFile.ReadWrite); 

Credits go to the author for this answer .

0
source share

All Articles