我在从QTreeWidget
迁移到QtreeView
时遇到问题。 QTreeWidget
显而易见且微不足道的事情似乎是不可能的。具体来说:我有一个带有树视图的主窗口。 TreeView使用我实现的模型,但不是直接 - 通过QSortFilterProxyModel
设置为树的模型。现在,用户激活树中的项目,主窗口接收信号itemActivated(QModelIndex item)
。如何判断哪些基础数据项已激活?数据是一个向量,因此使用TreeWidget我可以在QTreeWidgetItem
中存储项目的向量索引,但QModelIndex
甚至没有setData
API。
答案 0 :(得分:2)
如何判断哪些基础数据项已激活?
通过反转代理模型:
// supposing to connect this to your itemActivated signal
void onItemActivated(const QModelIndex &index)
{
QModelIndex originalIndex = proxyModel->mapToSource(index);
originalModel->doSomething(originalIndex);
}
答案 1 :(得分:1)
您可以在源模型中定义自定义角色,返回基础数据或标识符(如果有的话)作为变体。这样做的优势在于它可以与之间的任意数量的代理模型一起使用,因为数据将不加改变地传递给模型,现在需要映射索引。
假设一个模型列出了联系人,其值为struct / class Contact
,用于保存数据。
这需要通过Contact
注册Q_DECLARE_METATYPE
。
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
...
}
索引可以来自联系模型本身,也可以是其上的任何代理 - 此处的代码无需关注。
答案 2 :(得分:0)
存储数据的模型。视图中的项目/ 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
转化的问题,请参阅此问题的其他答案。
总结:QAbstractItemModel::data( const QModelIndex & index)
一旦您定义了特定QModelIndex
,就会为您提供数据。