2016-03-08 124 views
3

我的問題是,我如何指定一個自定義對象作爲從QAbstractListModel派生的模型中的角色,因此當在ListView內可視化時,我可以訪問其成員變量。到這裏有一個例子是一些簡單的代碼示例:如何將自定義對象定義爲QAbstractListModel中的角色?

這是我代表我的自定義對象類:的

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

    private: 
    QString name; 
    QString type; 
}; 

這是覆蓋data()函數現在的樣子(但不工作),我MyModelQAbsractListModel得出:

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:=>修復需要拷貝構造函數

當我在我的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

我在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) 

這是覆蓋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(); 
    } 

,我有p均其它功能osted原來是一樣的。

+0

你會得到什麼錯誤信息? – sk2212

回答

2

首先,您需要爲Qt metatype系統聲明您的自定義對象。你應該使用Q_DECLARE_METATYPE這個宏。您也可能需要使用qRegisterMetaType函數。然後你應該註冊你的對象來使用QML。你應該使用qmlRegisterType函數。

另外請確保您使用Q_INVOKABLE作爲您的對象方法。

+0

我要試一試,會回來的結果! – Silex

+0

不幸的是,只要我把'Q_DECLARE_METATYPE'放在我的MyCustomObject下面,就會出現錯誤:調用隱式刪除'MyCustomObject'的拷貝構造函數。 (有關更詳細的錯誤信息,請參閱我的EDIT1) – Silex

+1

也許您應該先閱讀文檔?可以註冊任何具有公共默認構造函數,公共構造函數和公共析構函數的類或結構。 – Evgeny