无法将动态创建的对象数组从 qml 发送到 c++ 作为方法参数

Can't send array of dynamically created objects from qml to c++ as method parameter

本文关键字:c++ 参数 方法 qml 动态 创建 数组 对象      更新时间:2023-10-16

我正在创建注册的qml对象并将它们存储在javascript数组中。我想将它们作为QVariantList方法参数发送到 c++。下面是代码。但是Backend::sendItems方法的第一个回合没有打印尺寸。奇怪的是,它只打印"ze",没有其他线程被中途中断。我做错了什么?你也可以建议另一种实现我想要的方法。

主.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "backend.h"
#include "custom_class.h"
void register_Qml_types() {
  qmlRegisterType<Backend>("customApi", 1, 0, "Backend");
  qmlRegisterType<CustomClass>("customApi", 1, 0, "CustomClass");
}
int main(int argc, char **argv)
{
  QGuiApplication app(argc, argv);
  register_Qml_types();
  QQmlApplicationEngine engine;
  engine.load(QUrl("qrc:/main.qml"));
  return app.exec();
}

custom_class.h

#ifndef CUSTOM_H
#define CUSTOM_H
#include <QString>
#include <QObject>
class CustomClass : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QString name READ name WRITE setName)
public:
  CustomClass(QObject* parent = 0)
    : QObject(parent)
  {}
  CustomClass(QString name) {
    name_ = name;
  }
  CustomClass(const CustomClass& item) {
    name_ = item.name_;
  }
  QString name() const {
    return name_;
  }
  void setName(QString name) {
    name_ = name;
  }
private:
  QString name_;
};
Q_DECLARE_METATYPE(CustomClass)
#endif

后端.h

#ifndef BACKEND_H
#define BACKEND_H
#include <iostream>
#include <typeinfo>
#include <QObject>
#include <QList>
#include <QVariant>
#include "custom_class.h"
class Backend : public QObject
{
  Q_OBJECT
public:
  Backend(QObject* parent = nullptr)
    : QObject(parent)
  {}
  Q_INVOKABLE void sendItems(const QVariantList& list) {
    std::cout << "size " + list.size() << std::endl;
    list_.clear();
    for(const QVariant& variant : list) {
      if(variant.canConvert<CustomClass>()) {
        CustomClass* custom = new CustomClass(variant.value<CustomClass>());
        list_.append(custom);
        std::cout << "converted" << std::endl;
      }
    }
  }
private:
    QList<CustomClass*> list_;
};
#endif

主.qml

import QtQuick.Window 2.11
import QtQuick.Controls 1.4
import QtQuick 2.11
import customApi 1.0
Window {
  id: root
  visible: true
  width: 500
  height: 500
  property var items: []
  Backend {
    id: backend
  }
  Row {
    Button {
      text: "button1"
      onClicked: {
        var item1 = Qt.createQmlObject("import customApi 1.0; CustomClass { name: "first-name" }", root);
        var item2 = Qt.createQmlObject("import customApi 1.0; CustomClass { name: "second-name" }", root);
        items.push(item1);
        items.push(item2);
      }
    }
    Button {
      text: "button2"
      onClicked: {
        backend.sendItems(items);
      }
    }
  }
}

我看到你正在打印:

std::cout << "size " + list.size() << std::endl;

但相反,您必须分开,因为可能它正在考虑 size(( 作为字符。

std::cout << "size "<< list.size() << std::endl;

另一方面,QObject存储为指针,即:CustomClass *,并且您正在创建其他CustomClass *而不是QML中的(我假设您希望在视图中具有相同的项目(

解决方案是下一个:

Q_INVOKABLE void sendItems(const QVariantList& list) {
    std::cout << "size "<< list.size() << std::endl;
    list_.clear();
    for(const QVariant& variant : list) {
        if(variant.canConvert<CustomClass *>()) {
            CustomClass* custom = variant.value<CustomClass*>();
            list_.append(custom);
            std::cout << "converted " << custom->name().toStdString() << std::endl;
        }
    }
}

您可以在以下链接中找到测试项目