在插槽中接收C++对象



我想通过信号槽向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

相关内容

  • 没有找到相关文章