如何将指向字符串属性的指针从QML传递给C ++?
当我试图以明显的方式做到这一点时,我收到了这个错误:
qrc:/NewAccount.qml:236: Error: Unknown method parameter type: QString*
这意味着,在调用new_account.error_string
(Q_INVOKABLE)方法时,QML引擎无法将save_account
属性转换为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之间交换数据时处理对象所有权更安全。
答案 0 :(得分:1)
正如我在评论中所说,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 }
}
}
答案 1 :(得分:1)
使用Qt,C ++ API和QML API完全不同,实际上是不兼容的层。为了使整个过程工作,有很多来回的数据转换。当谈到像字符串这样的原语时,你并没有真正掌控它。所以只是从脑子里想出来。
如果要访问特定对象的特定属性,则需要传递将作为指针接收的对象和属性名称,然后可以通过QObject
通过其名称字符串访问该属性名称s property()
和setProperty()
。
但在你的情况下,这完全是多余的,只需传递字符串本身。