簡體   English   中英

如何在QML Javascript中創建和使用C ++對象

[英]How to create and use C++ objects in QML Javascript

我的應用程序同時使用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");

理想情況下,我只需要在Javascript中而不在QML中使用這些對象。

我嘗試了很多示例並閱讀了所有文檔,但仍然無法解決我的問題。

所以我的問題是:

  • 如何在Javascript中實例化C ++中定義的對象? 我嘗試了var obj = Qt.createComponent("MyObject"); 但似乎無效。 是否可以用普通的JS樣式定義新對象var obj = new MyObject;
  • 如何在javascript中訪問此創建的對象? 我嘗試了obj.someFunction(“ xxx”),但遇到了一些錯誤TypeError: Property 'someFunction' of object QQmlComponent(0x3605f5c0) is not a function. 我在這里做錯了什么? 我的對象來自QObject,而不來自QQmlComponent。

您的對象不是Component ,但是可以改用Qt.createQmlObject

文檔非常清楚,但困惑似乎在等式的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周就能熟練地工作)。

您可以使用

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

這不是完美的,但滿足了我的要求。 希望對您有幫助。

這是一個設想的TextFile類的示例。 首先,我們需要一個已經建議的工廠類:

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

注意:此類比必要的要復雜一些。 應該創建多個類型。 現在已經有了工廠類,我們需要告訴QML / QJSEngine在調用TextFile的運算符new時該怎么做。

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

現在,即使有參數,我們也可以根據需要實例化TextFile

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

感謝這個答案的作者。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM