如何在 QAbstractListModel 中将自定义对象定义为角色



我的问题是,如何将自定义对象指定为从QAbstractListModel派生的模型中的角色,以便在ListView中可视化它时可以访问其成员变量。这里有一个简单的代码示例:

这是我的类,表示我的自定义对象:

class MyCustomObject {
  public:
    MyCustomObject(Qstring name, Qstring type);
    QString getName();
    QString getType();
  private:
    QString name;
    QString type;
};

这就是从QAbsractListModel派生的MyModel的被覆盖的data()函数现在的样子(但它不起作用):

QVariant MyModel::data(const QModelIndex &index, int role) const {
    if (index.row() < 0 || index.row() > m_atoms.count()) {
    //if (!index.isValid()) {
        return QVariant();
    }
    const MyData &data = m_data[index.row()];
    if(role == SomeRole) {
        return data.someString()
    }
    else if (role == MyCustomRole) {
        return data.myCustomObject; // How can I do this?
    }
    return QVariant();
}

在这里,我指定MyModel中的角色名称:

QHash<int, QByteArray> AtomModel::roleNames() const {
    QHash<int, QByteArray> roles;
    roles[SomeRole] = "someRole";
    roles[MyCustomRole] = "myCustomRole";
    return roles;
}

这就是我的ListView在 QML 代码中的样子,并举例说明我想如何在委托中访问MyCustomObject成员变量:

ListView {
        width: 400
        height: 400
        model: myModel
        delegate: Text {
            text: "Type: " + myCustomRole.getType() + ", Name: " + myCustomRole.getName() + ", some string: " someRole
        }
    }

编辑1: =>修复所需的复制构造函数

当我在MyCustomObject下添加Q_DECLARE_METATYPE时,我收到以下错误:

call to implicitly-deleted copy constructor of `MyCustomObject`
in instantiation of member function 'QtMetaTypePrivate::QMetaTypeFunctionHelper<MyCustomObject, true>::Construct' requested here
in instantiation of function template specialization 'qRegisterNormalizedMetaType<MyCustomObject>' requested here QtMetaTypePrivate::QMetaTypeFunctionHelper<T>::Construct,
    return qRegisterNormalizedMetaType<T>(normalizedTypeName, dummy, defined);
in instantiation of function template specialization 'qRegisterMetaType<MyCustomObject>' requested here
Q_DECLARE_METATYPE(MyCustomObject)
expanded from macro 'Q_DECLARE_METATYPE'
#define Q_DECLARE_METATYPE(TYPE) Q_DECLARE_METATYPE_IMPL(TYPE)
expanded from macro 'Q_DECLARE_METATYPE_IMPL' 
      const int newId = qRegisterMetaType< TYPE >(#TYPE,
copy constructor of 'MyCustomObject' is implicitly deleted because base class 'QObject' has a deleted copy constructor
class MyCustomObject : public QObject
'QObject' has been explicitly marked deleted here Q_DISABLE_COPY(QObject)
expanded from macro 'Q_DISABLE_COPY'
       Class(const Class &) Q_DECL_EQ_DELETE;

编辑2:

因此,我添加了@Evgeny建议的所有必要功能。我的代码现在可以编译没有错误,但我在运行时收到一个 qml 错误,说: TypeError: Property 'getType' of object QVariant(MyCustomObject) is not a function

我在getType()方法前面添加了Q_INVOKABLE,并且我还从public QObject派生MyCustomObject类。我在MyCustomObject头文件的底部添加了Q_DECLARE_METATYPE。在MyCustomObject的构造函数中,我调用qRegisterMetaType<MyCustomObject>("MyCustomObject"),在我的main中,我也像这样注册类qmlRegisterType<MyCustomObject>("com.test.mycustomobject", 1, 0, "MyCustomObject")

这就是MyCustomObject类现在的样子:

class MyCustomObject : public QObject {
  public:
    MyCustomObject();
    MyCustomObject(Qstring name, Qstring type);
    MyCustomObject(const MyCustomObject& obj);
    ~MyCustomObject();
    Q_INVOKABLE QString getName();
    Q_INVOKABLE QString getType();
  private:
    QString name;
    QString type;
};
Q_DECLARE_METATYPE(MyCustomObject)

这就是我从QAbsractListModel派生的MyModel被覆盖的data()函数现在的样子:

QVariant MyModel::data(const QModelIndex &index, int role) const {
        if (index.row() < 0 || index.row() > m_atoms.count()) {
        //if (!index.isValid()) {
            return QVariant();
        }
        const MyData &data = m_data[index.row()];
        if(role == SomeRole) {
            return data.someString()
        }
        else if (role == MyCustomRole) {
            QVariant var; // this is the part, which has changed
            var.setValue(data.myCustomObject);
            return var;
        }
        return QVariant();
    }

我最初发布的所有其他功能都是相同的。

首先,您需要为 Qt 元类型系统声明自定义对象。为此,您应该使用Q_DECLARE_METATYPE宏。此外,您可能需要使用qRegisterMetaType功能。然后,您应该注册您的对象以将其用于 QML。您应该为此使用qmlRegisterType函数。

此外,请确保对对象方法使用 Q_INVOKABLE

相关内容

  • 没有找到相关文章

最新更新