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

久未见 提交于 2019-12-03 12:17:27
OliJG

Your object isn't a Component, but you can use Qt.createQmlObject instead.

The documentation is pretty clear but the confusion looks like it is on the QML side of the equation. This should get you started:

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

The QML is below:

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

On clicking you should see the strings in the output (I didn't compile or test this). Be sure to register the type in your main class.

You should check out the local storage object if you're using SQL on a mobile device. It is a pretty simple callback API that works with SQLite. I use it for desktop applications and don't have much trouble. Returning lists is a little annoying so just try to stick to simple types for easy JavaScript integration.

I hope that helps. I absolutely love working in QML, it is quite fun once you learn it (1-2 weeks to be proficient enough to work).

You can use

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

CppCreator is an QObject to create other c++ object

Q_INVOKABLE QObject* Create(const QString& type_name);

Then you can create c++ object in qml js like

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

It is not perfect but satisfied my requirement. Hope it helps you.

Here is an example with an imagined 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 bit more complicated than necessary. It is supposed to create multiple types. Now that we have the factory class in place, we need to tell the QML/QJSEngine what to do when calling the operator new for 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 instanciate our TextFile as desired, even with parameters:

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

Credits go to the author of this answer.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!