繁体   English   中英

如何使用Q_PROPERTY公开自定义对象的列表

[英]How to expose list of custom objects with Q_PROPERTY

我有一个非常简单的类,具有2个属性; 关键和价值:

KeyValue.h:

class KeyValue : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QString key READ getKey WRITE setKey NOTIFY keyChanged)
  Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)

 public:
  KeyValue(const QString& key, const QString& value, QObject* parent = 0);  

 signals:
  void keyChanged();
  void valueChanged();

 private:
  QString _key;
  QString _value;

  QString getKey() const;
  QString getValue() const;

  void setKey(const QString& key);  
  void setValue(const QString& value);
};
Q_DECLARE_METATYPE(KeyValue)

在另一个类中,我想要一个包含KeyValue对象列表的属性,因此我可以将此列表用作QML中的模型。

控制器

class Controller : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QList<KeyValue*> items READ getItems NOTIFY itemsChanged)

 public:
  explicit Controller(QObject* parent = 0);

 signals:
  void itemsChanged(); 

 private:
  QList<KeyValue*> getItems() const;
};

我希望能够通过以下方式在QML中使用它:

import QtQuick 2.7
import customqml 1.0

Item{
  Controller{
    id: controller
  }
  Repeater{
    model: controller.items
    Text{
      text: modelData.key + ": " + modelData.value
    }
  }
}

这两个类都在我的main.cpp文件中注册:

qmlRegisterType<KeyValue>("customqml", 1, 0, "KeyValue");
qmlRegisterType<Controller>("customqml", 1, 0, "Controller");

上面的代码不起作用,因为我显然无法直接将QList公开给QML。 我曾尝试使用QAbstractItemModel和QQmlListProperty,但无法使其正常工作。 谁能指出我正确的方向?

我的主要问题是Controller类中items属性的类型以及getItems方法的返回值。

如果这有任何区别,我正在使用Qt 5.9。

注意:

  • 吸气剂和吸气剂通常是公共的,除了例外,因此将其移到公共部分

  • 从QObject继承的类不需要QMetaType,因为当您要传输该类的数据时,将使用指针。

QML通过Q_PROPERTY并非所有数据类型都支持,因此一种可能的解决方案是通过诸如

  • QList<QObject *>

class Controller : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QList<QObject *> items READ getItems NOTIFY itemsChanged)
public:
    explicit Controller(QObject *parent = nullptr);
    QList<QObject *> getItems() const;
signals:
    void itemsChanged();
private:
    QList<KeyValue *>key_values_list;
};

...
QList<QObject *> Controller::getItems() const
{
    QObjectList l;
    for(auto e: key_values_list)
        l << e;
    return l;
}
  • QVariantList

class Controller : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QVariantList items READ getItems NOTIFY itemsChanged)
public:
    explicit Controller(QObject *parent = nullptr);
    QVariantList getItems() const;
signals:
    void itemsChanged();
private:
    QList<KeyValue *>key_values_list;
};

...
QVariantList Controller::getItems() const
{
    QVariantList l;
    for(auto e: key_values_list)
        l.append(QVariant::fromValue(e));
    return l;
}

其他选项是实现模型,下面的示例仅显示只读模型:

键值模型

#ifndef KEYVALUEMODEL_H
#define KEYVALUEMODEL_H

#include "keyvalue.h"

#include <QAbstractListModel>

class KeyValueModel : public QAbstractListModel
{
    Q_OBJECT

public:
    explicit KeyValueModel(QObject *parent = nullptr)
        : QAbstractListModel(parent)
    {
        key_values_list = {new KeyValue{"k", "v"}, new KeyValue{"k2", "v2"}};
    }
    int rowCount(const QModelIndex &parent = QModelIndex()) const override
    {
        if (parent.isValid())
            return 0;
        return key_values_list.length();
    }
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override
    {
        if (!index.isValid())
            return QVariant();
        if(index.row() >= 0 && index.row() < rowCount())
            return QVariant::fromValue(key_values_list[index.row()]);
        return QVariant();
    }
private:
    QList<KeyValue* >key_values_list;
};

#endif // KEYVALUEMODEL_H

class Controller : public QObject
{
    Q_OBJECT
    Q_PROPERTY(KeyValueModel* items READ getItems NOTIFY itemsChanged)
public:
    explicit Controller(QObject *parent = nullptr);
    KeyValueModel* getItems() const;
signals:
    void itemsChanged();
private:
    KeyValueModel *model;
};

...
Text{
    text: display.key + ": " + display.value
}
...

并且以类似的方式可以实现QQmlListProperty,在文档中有很多示例。

如果您想要一个具有添加/删除对象和更改数据的复杂模型,则应考虑对QAbstractListModel进行子类化。

作为一种简单但不太灵活的方法,您可以使用QVariantList并使Controller类成为值类型。 你需要:

  • 控制器头文件末尾的宏Q_DECLARE_METATYPE(Controller)。
  • Controller的副本构造函数
  • Controller的默认构造函数

Q_PROPERTY类型和返回值就是QVariantList。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM