[英]QTreeView: maintaining mapping between QModelIndex and underlying data
我從QTreeWidget
遷移到QtreeView
遇到問題。 對於QTreeWidget
來說,顯而易見的瑣碎事情似乎是不可能的。 具體來說:我有一個帶有樹視圖的主窗口。 TreeView使用我已經實現的模型,但不是直接使用–通過QSortFilterProxyModel
設置為樹的模型。 現在,用戶激活樹中的一個項目,主窗口接收到一個信號itemActivated(QModelIndex item)
。 我如何知道底層數據中的哪一項已激活? 數據是向量,因此使用TreeWidget可以將項目的向量索引存儲在QTreeWidgetItem
,但是QModelIndex
甚至沒有setData
API。
我如何知道底層數據中的哪一項已激活?
通過反轉代理模型:
// supposing to connect this to your itemActivated signal
void onItemActivated(const QModelIndex &index)
{
QModelIndex originalIndex = proxyModel->mapToSource(index);
originalModel->doSomething(originalIndex);
}
您可以在源模型中定義自定義角色,返回基礎數據或標識符(如果有)作為變體。 這樣做的好處是,它可以在任意數量的代理模型之間使用,因為數據將不經更改地通過模型傳遞,並且現在需要索引映射。
假設有一個列出聯系人的模型,值struct / class Contact
保存數據。 這要求通過Q_DECLARE_METATYPE
注冊Contact
。
class ContactModel ... {
...
enum Role {
ContactRole=Qt::UserRole,
ContactIdRole
};
QVariant data(...) const {
...
const Contact& contact = ...get from datastructure...
...
switch (role) {
...
case ContactRole:
return QVariant::fromValue( contact );
case ContactIdRole:
return contact.id;
}
}
...
並在接收索引的代碼中:
void SomeWidget::indexSelected(const QModelIndex& index)
{
const int id = index.data(ContactModel::ContactIdRole).toInt();
// look up Contact, do something with it
//or:
const Contact contact = index.data(ContactModel::ContactRole).value<Contact>();
// do something with the contact
...
}
索引可以來自聯系人模型本身,也可以來自於它之上的任何代理-此處的代碼不必關心。
用於存儲數據的模型。 該數據不再由視圖中的items / QModelIndex
擁有。 QModelIndex
只是在視圖和模型之間傳遞的唯一標識符(在這種情況下,通過QSortFilterProxyModel
)。 該模型應該繼承QAbstractItemModel
,它具有一些需要定義的純虛函數(您可以從http://qt-project.org/doc/qt-4.8/itemviews-simpletreemodel.html復制樣板)。 例如,您將必須定義QAbstractItemModel::data( const QModelIndex & index, int role = Qt::DisplayRole)
,它定義與特定QModelIndex
對應的數據。
QSortFilterProxyModel位於視圖和模型之間,但不更改模型的原理。 有關如何處理QModelIndex
轉換, QModelIndex
問題的其他答案。
總結QModelIndex
一旦定義了QAbstractItemModel::data( const QModelIndex & index)
它將為您提供特定QModelIndex
的數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.