我想通过signal-slot发送一个C ++对象到QML:
class TaskInfo : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ taskName)
...
// constructors
public:
TaskInfo();
TaskInfo(QIODevice *in);
TaskInfo(TaskInfo &&taskInfo);
TaskInfo(const TaskInfo &taskInfo); // it's just copy all variable
...
}
我有一个类将TaskInfo对象发送到QML:
class DLDataConverter : public QObject
{
Q_OBJECT
signals:
void taskAdded_testQML(const TaskInfo taskInfo);
void taskAdded_useQString(const QString taskInfo);
...
}
我也发出信号并用QML接收:
void DLDataConverter::addItem(const TaskInfo &taskInfo)
{
emit taskAdded_testQML(taskInfo);
emit taskAdded_useQString(taskInfo.getInfoToString());
}
QML代码:
Connections {
target: DLDataConverter
onTaskAdded_testQML: {
console.log(taskInfo);
}
onTaskAdded_useQString: {
console.log(taskInfo);
}
}
onTaskAdded_useQString信号工作正常,但onTaskAdded_testQML打印'undefined'。
我已经注册了这些类型:
qmlRegisterType<TaskInfo>("taskInfo", 1, 0, "TaskInfo");
qmlRegisterSingletonType<DLDataConverter>("Singleton.DLDataConverter", 1, 0, "DLDataConverter", dataObj);
我可以创建TaskInfo
对象并且效果很好:
TaskInfo{
id: t
}
Connections {
target: DLDataConverter
onTaskAdded_testQML: {
console.log(t.name); // print default value, is "Noname"
console.log(taskInfo); // print 'undefined'
}
}
答案 0 :(得分:3)
QML使用来自Qt的数据,将每个参数转换为QVariant
,然后,如果可能,将其转换为本机JavaScript值。如果它们无法转换为JS,您仍然可以使用JS复制并传递它们,但您无法使用它们。在不扩展QVariant
的情况下,只有QObject*
可以保存在QVariant
中,并且JS是线程,它的属性,槽和信号对JS是可见的。任何指向对象的指针(其类派生自QObject
)都会被QObject*
隐式转换为QVariant
。因此,您可以自由地定义指向您的类的指针的信号:
class DLDataConverter : public QObject
{
Q_OBJECT
signals:
void taskAdded_testQML(TaskInfo *taskInfo);
void taskAdded_useQString(const QString taskInfo);
...
}
指针介绍了对象生命周期的问题,因此您一定要详细了解如何manage the ownership of objects。 如果你在Qml中创建你的对象:
TaskInfo{
id: t
}
您创建的对象具有parent
,其生命周期决定了对象本身的生命周期。指针绑定到本地QML上下文中的名称t
。