在插槽中接收 C++ 对象

Receiving a C++ object in a 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
    ...
}

我有一个 class 可以将 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'
    }
}

QML 通过将每个参数转换为 QVariant 并在可能的情况下转换为原生 JavaScript 值来使用来自 Qt 的数据。如果不能转成JS,你还可以用JS复制传过去,但是你就不能用了。在不扩展QVariant的情况下,只有QObject*可以在QVariant中被持有,并且是JS线程,它的属性、槽和信号对JS是可见的。 class 派生自 QObject 的任何指向对象的指针都会被 QVariant 隐式转换为 QObject*。所以你可以自由定义指向你的 class 的指针信号为:

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