维护QModelIndex和基础数据之间的映射

维护QModelIndex和基础数据之间的映射

本文介绍了QTreeView:维护QModelIndex和基础数据之间的映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have problems migrating from QTreeWidget to QtreeView. Things that were obvious and trivial with QTreeWidget seem to be impossible with view. Specifically: I have a main window with a treeview in it. TreeView uses the model I've implemented, but not directly – through QSortFilterProxyModel that is set as a tree's model. Now, the user activates an item in the tree and main windows receives a signal itemActivated(QModelIndex item). How can I tell which item of the underlying data was activated? Data is a vector, so with TreeWidget I could just store an item's vector index in the QTreeWidgetItem, but QModelIndex doesn’t even have setData API.

推荐答案

您可以在源模型中定义自定义角色,返回基础数据或标识符(如果有)作为变体.这样做的好处是,它可以在任何数量的代理模型之间使用,因为数据将不更改地通过模型传递,并且现在需要索引映射.

You can define custom roles in your source model, returning the underlying data or an identifier (if there's one) as variant. This has the advantage it works with any number of proxy models in between, as the data will be passed through the models unaltered and now mapping of indexes is required.

假设一个模型列出了联系人,值struct/class Contact保存数据.这要求通过Q_DECLARE_METATYPE注册Contact.

Assuming a model listing contacts, with a value struct/class Contact holding the data.This requires Contact to be registered via 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

    ...
}

索引可以来自联系人模型本身,也可以来自于它之上的任何代理-此处的代码不必关心.

The index can be from the contact model itself, or any proxy on top of it - the code here doesn't have to care.

这篇关于QTreeView:维护QModelIndex和基础数据之间的映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 01:35