QTreeView:维护QModelIndex和底层数据之间的映射

时间:2013-09-22 08:09:37

标签: c++ qt qtreeview qabstractitemmodel

我在从QTreeWidget迁移到QtreeView时遇到问题。 QTreeWidget显而易见且微不足道的事情似乎是不可能的。具体来说:我有一个带有树视图的主窗口。 TreeView使用我实现的模型,但不是直接 - 通过QSortFilterProxyModel设置为树的模型。现在,用户激活树中的项目,主窗口接收信号itemActivated(QModelIndex item)。如何判断哪些基础数据项已激活?数据是一个向量,因此使用TreeWidget我可以在QTreeWidgetItem中存储项目的向量索引,但QModelIndex甚至没有setData API。

3 个答案:

答案 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,就会为您提供数据。