簡體   English   中英

將指向QML字符串屬性的指針傳遞給C ++

[英]Passing a pointer to QML string property to C++

如何將指向字符串屬性的指針從QML傳遞到C ++?

當我嘗試以明顯的方式執行此操作時,出現以下錯誤:

qrc:/NewAccount.qml:236: Error: Unknown method parameter type: QString*

這意味着QML引擎在調用save_account (Q_INVOKABLE)方法時無法將new_account.error_string屬性轉換為C ++

這是我在QML中的代碼:

import myproject.aewm.ethkey 1.0
import myproject.aewm.walletaccount 1.0
...
id: new_account
property EthKey key: EthKey{}
property WalletAccount account: WalletAccount{}
property string error_string: ""
....
if (aewm_obj.save_account(key,account,new_account.error_string)) {
    wallet_accounts_tabbar.currentIndex=0
} else {
    console.log("error occurred:"+new_account.error_string)
}

其中aewm_obj是C ++類型(在QML中注冊),而save_account在C ++中聲明為:

Q_INVOKABLE     bool save_account(EthKey *key, WalletAccount *account, QString *err_str);

文檔說(QML) string屬性是QString對象,並且這些類型是從C ++和QML自動轉換而來的。 qmlRegisterType()調用之后,我將指針傳遞給自定義的QObject派生類,而沒有任何問題,那么為什么不能對字符串做同樣的事情?

我以為可能不支持字符串指針,所以我嘗試添加以下行:

qRegisterMetaType<QString*>("QString*");

但是更改之后,我在C ++端收到的指針為0x0,我遇到了段錯誤。

因此,如何將指向QML字符串屬性的指針從QML傳遞給C ++?

或者,您認為我也應該向qmlRegisterType()注冊QString類嗎? 我嘗試過,但是遇到了一些編譯問題,所以我認為它不會編譯。

最后一種解決方案是創建一個內部帶有QString的自定義對象,並將指向該對象的指針從QML發送到C ++。 但是,如果存在QString,為什么不找到使用它的方法呢?

非常感謝您的評論。 我絕對想使用指針,當在C ++和QML之間交換數據時,它比處理對象所有權更安全。

正如我在評論中所說,QML僅傳遞來自QObject的指針,而QString不是QObject

我認為您提供的問題解決方法不正確,您可以在對象中創建一個屬性,該對象執行具有錯誤消息的計算,如下所示。

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

class Foo: public QObject{
    Q_OBJECT
    Q_PROPERTY(QString errorMessage READ errorMessage)
public:
    using QObject::QObject;
    Q_INVOKABLE bool process(int a, int b, int res){
        bool status;
        // some operation
        status = (a+b) == res;
        mErrorMessage = status? "": QString("error message: %1 + %2 is different to %3").arg(a).arg(b).arg(res);
        return status;
    }
    QString errorMessage() const{
        return mErrorMessage;
    }

private:
    QString mErrorMessage;
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QGuiApplication app(argc, argv);

    qmlRegisterType<Foo>("com.eyllanesc.org", 1, 0, "Foo");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

#include "main.moc"

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 1.4

import com.eyllanesc.org 1.0

Window {
    visible: true
    width: 640
    height: 480

    Foo{ id: foo }

    Row{
        SpinBox{ id: a }
        SpinBox{ id: b }
        SpinBox{ id: c }

        Button{
            text: "process"
            onClicked: {
                var message;
                if(foo.process(a.value, b.value, c.value)){
                    message = "correct"
                    console.log("successful")
                }
                else{
                    message = foo.errorMessage
                    console.log("error is "+ message)
                }
                txt.text = message
            }
        }
        Label{ id: txt }
    }
}

使用Qt,C ++ API和QML API完全不同,並且幾乎不兼容。 為了使整個事情正常進行,有很多來回的數據轉換。 當涉及字符串之類的基元時,您實際上並沒有控制權。 因此,請把這個想法從腦子里弄出來。

如果要訪問特定對象的特定屬性,則需要傳遞將作為指針接收的對象和屬性名稱,然后可以通過其名稱字符串通過QObjectproperty()setProperty()

但在您的情況下,這完全是多余的,只需傳遞字符串本身即可。

暫無
暫無

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

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