我想通过信号槽向QML发送一个C++对象:
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打印"未定义"。
我已经注册了这些类型:
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'
}
}
QML通过将每个参数转换为QVariant
并在可能的情况下转换为本地JavaScript值来使用Qt中的数据。如果它们不能转换为JS,你仍然可以用JS复制和传递它们,但你将无法使用它们。在不扩展QVariant
的情况下,只有QObject*
可以保存在QVariant
中,并且被JS线程化,其属性、槽和信号对JS可见。任何指向对象的指针(其类派生自QObject
)都会被QVariant
隐式转换为QObject*
。因此,您可以自由地将指向类的指针的信号定义为:
class DLDataConverter : public QObject
{
Q_OBJECT
signals:
void taskAdded_testQML(TaskInfo *taskInfo);
void taskAdded_useQString(const QString taskInfo);
...
}
指针引入了对象生存期的问题,因此您肯定应该了解更多关于如何管理对象所有权的信息。如果你在Qml中创建这样的对象:
TaskInfo{
id: t
}
您创建了一个具有parent
的对象,其生存期决定了对象本身的生存期。指针被绑定到本地QML上下文中的名称t
。