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

时间:2016-03-08 03:23:09

标签: qml qt5 qabstractlistmodel

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

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

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

  private:
    QString name;
    QString type;
};

这是data()来自MyModel的{​​{1}}覆盖QAbsractListModel函数现在的样子(但不起作用):

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

        }
    }

EDIT1:=&gt;修复所需的复制构造函数

当我在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;\

EDIT2:

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

我在Q_INVOKABLE方法前添加了getType(),我还从MyCustomObject派生了public QObject类。我在Q_DECLARE_METATYPE标头文件的底部添加了MyCustomObject。在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)

这是data()MyModel派生的QAbsractListModel的覆盖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(); } 函数的样子:

import random

random_number = random.randint(1,100)
max_tries = 100 
tries = 0
left = 0
right = 100
found = False


def get_number():
    try:
        guess = int(input("Guss a random number between {} and {}".format(left, right)))            
        if guess > right or guess < left:
            print("That number is not between {} and {}".format(left, right))
        return guess
    except:
        print("That's not a whole number!")
        get_number()

def update_range(guess):
    if guess >= left:
        left = guess
    else:
        right = guess        

while tries <= max_tries and not found:
    guess = get_number()
    tries=+1
    if guess == random_number:
        print("Congratulations! You are correct!")
        print("It took you {} tries.".format(tries))
        found = True
    else:
        update_range(guess)

  if not found:
      print("Sorry, but my number was {}".format(random_number))
      print("You are out of tries. Better luck next time.")

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

1 个答案:

答案 0 :(得分:2)

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

另外,请确保使用Q_INVOKABLE作为对象方法。