首页 > 解决方案 > 无法将动态创建的对象数组从 qml 发送到 c++ 作为方法参数

问题描述

我正在创建注册的 qml 对象并将它们存储在 javascript 数组中。我想将它们作为QVariantList方法参数发送给 c++。下面是代码。但是第一个Backend::sendItems方法不打印大小。奇怪的是,它只打印“ze”,而没有其他像线程一样被中途中断的东西。我究竟做错了什么?您还可以提出另一种实现我想要的方法。

主文件

#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

main.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);
      }
    }
  }

}

标签: c++qtqmlqt5

解决方案


我看到你正在打印:

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

但是您必须分开,因为它可能将 size() 视为 char。

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

另一方面QObjects 存储为指针,即: 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;
        }
    }
}

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


推荐阅读