2013-01-20 14 views
3

我有一個使用internalpointer()的書面模型(myModel),他的data()實現。 我想過濾一棵樹(基於myModel)使用QSortFilterProxyModel,Qt重新實現QSortFilterProxyModel :: data()而模型使用的是內部指針()

我得到它的工作,只有當我嘗試從樹中獲取任何數據我的應用程序崩潰。

我認爲它是因爲在調用樹數據時,期望獲得myModel indexModel,我得到了myQSortFilterProxyModel indexModel。

myItem *myModel::getItem(const QModelIndex &index) const 
{ 
    if (index.isValid()) { 
     myItem *item = static_cast<myItem*>(index.internalPointer()); 
     if (item) return item; 
    } 
    return rootItem; 
} 

基於myModel data()使用internalPointer()

QVariant myModel::data(const QModelIndex &index, int role) const 
{ 
    if (!index.isValid()) 
     return QVariant(); 

    if (role != Qt::DisplayRole && role != Qt::EditRole) 
     return QVariant(); 

    myItem *item = getItem(index); 

    return item->data(index.column()); 
} 

設定基於myModel螞蟻之間的過濾器模型中的樹

void myTree::myInit() 
{ 
... 
    myModel *model = new myModel(); 
    proxyModel = new mySortFilterProxyModel(this); 
    proxyModel->setSourceModel(model); 
    this->setModel(proxyModel); 
... 

myTree是QTreeView則子類。 我想用tree->model()來得到myModel模型

我該如何獲取源模型數據?

回答

0

由於您指出的原因,此方法不適用於代理模型。 只能在保證獲得屬於模型本身的索引的方法中訪問內部指針/標識,例如data()等。

獲取索引項目的更好方法是通過自定義作用:

enum Roles { 
    MyItemRole=Qt::UserRole 
}; 

QVariant data(const QModelIndex& index, int role) const { 
     ... 
     if (role == MyItemRole) 
      return QVariant::fromValue<MyItem>(item); 
     //MyItem or MyItem*, depending on whether it can be copied/has 
     // value semantics or not 
     ... 
} 

而且在使用代碼:

const MyItem item = index.data(MyModel::MyItemRole).value<MyItem>(); 

你需要Q_DECLARE_METATYPE(MyItem)(或MyItem *)的頭並在運行時調用qRegisterMetaType(),使MyItem/MyItem *可以作爲QVariant傳遞。

這種方法的優點是它可以工作,不管代理之間有什麼代理模型,代碼調用數據甚至不必知道代理。

+0

謝謝,但我已經在使用內部指針有課,我知道這是錯誤的方式去.. 我發現花葯解決方案,我重寫myTree ::模型() 和myTrre: :currentIndex() 給我myModel數據而不是proxyModel數據。 這對我更好,因爲我不需要更改任何原始代碼。 –

0

您只需要在調用getItem()之前調用mapToSource()。

下面是我用來更改特定類型項目的字體的data()方法。否則,它只是調用QSortFilterProxyModel的數據()。

virtual QVariant data(const QModelIndex & proxy_index, int role) const 
{ 
    QModelIndex source_index = mapToSource(proxy_index); 
    IT::TreeItem * item = IT::toItem(source_index); 
    if (role == Qt::FontRole && item->isMessage()) return _bold_font; 
    return QSortFilterProxyModel::data(proxy_index, role); 
}