在 QT 中,链接模型无法按预期工作

Posted

技术标签:

【中文标题】在 QT 中,链接模型无法按预期工作【英文标题】:In QT, chaining models does not work as expected 【发布时间】:2010-11-26 03:39:19 【问题描述】:

好的,我有一个非常基本的QStandardItemModel,里面有一些数字。我设法在QTableView 中显示它,没关系。我创建了一个新模型(QAbstractItemModelQAbstractProxyModel 的子类),它是现有模型的某种层 - 需要设置源模型,并且这个新层应该对真实模型进行一些转换.

我的问题是,在顶层,说“层模型”,data( const QModelIndex & index, int role ) 成员函数从未调用过,但是我想通过角色参数更改显示方法。

这是一个示例代码,它演示了原始模型的data(index,role) 始终被调用,而层模型的data(index,role) 永远不会被调用。为什么? QTableView 对象如何“跳过”顶层的data(index,role)

#include 
#include 
#include 

MyModel 类:公共 QStandardItemModel

民众:
    MyModel(const int r, const int c, QObject* parent = 0) : QStandardItemModel(r,c,parent) 
    QVariant 数据 ( const QModelIndex & index, int role = Qt::DisplayRole ) const 
        qDebug() itemFromIndex(index)->data(role);
    
;

MyProxyModel 类:公共 QAbstractProxyModel

民众:

    MyProxyModel(QObject* parent = 0) : QAbstractProxyModel(parent) 
    QModelIndex 索引( int 行,int 列,const QModelIndex & parent = QModelIndex() ) const 
        返回 this->sourceModel()->index(row,column,parent);
    
    QModelIndex 父级 ( const QModelIndex & index ) const 
        返回 this->sourceModel()->parent(index);
    
    QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const
    
        返回源索引;
    
    QModelIndex mapToSource ( const QModelIndex & proxyIndex ) const
    
        返回代理索引;
    
    QVariant 数据 ( const QModelIndex & index, int role = Qt::DisplayRole ) const 
        qDebug() sourceModel()->data(index,role);
    

    int rowCount ( const QModelIndex & parent = QModelIndex() ) const 
        返回 this->sourceModel()->rowCount(parent);
    
    int columnCount ( const QModelIndex & parent = QModelIndex() ) const 
        返回 this->sourceModel()->columnCount(parent);
    
;

int main(int argc, char *argv[])

    QApplication 应用程序(argc,argv);
    MyModel 模型(8, 2);
    我的代理模型我的模型;
    mymodel.setSourceModel(&model);

    QTableView 表视图;
    tableView.setModel(&mymodel);

    tableView.horizo​​ntalHeader()->setStretchLastSection(true);
    for (int row = 0; row 
    

【问题讨论】:

【参考方案1】:

因为QTableView使用模型索引来检索数据,大概是这样的。

QModelIndex index = model->index(row, column, parentIndex); 
index.data(Qt::DisplayRole);

您正在返回源模型的模型索引而不是代理模型的索引:

QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const 
    return this->sourceModel()->index(row,column,parent);

尝试将模型索引转换为代理模型的索引

QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const 
    return this->createIndex(row,column,row);

不要忘记将映射重写为源函数并从源函数映射。


解决方案

class MyTableProxyModel : public QAbstractProxyModel

    Q_OBJECT
public:
    MyTableProxyModel (QObject* parent = 0) 
        : QAbstractProxyModel(parent) 
    

    QModelIndex index(int row, int column, const QModelIndex& parent=QModelIndex()) const 
        return createIndex(row,column,row);
    

    QModelIndex parent(const QModelIndex &index) const 
        //Works only for non-tree models
        return QModelIndex();
    

    QModelIndex mapFromSource(const QModelIndex &source) const 
        return index(source.row(), source.column(), source.parent());
    

    QModelIndex mapToSource(const QModelIndex &proxy) const 
        return (sourceModel()&&proxy.isValid())
            ? sourceModel()->index(proxy.row(), proxy.column(), proxy.parent()) 
            : QModelIndex();
    

    QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const 
        qDebug() << "myproxymodel data";
        return mapToSource(index).data(role);
    

    int rowCount ( const QModelIndex & parent = QModelIndex() ) const 
        return sourceModel() ? sourceModel()->rowCount(parent) : 0;
    

    int columnCount ( const QModelIndex & parent = QModelIndex() ) const 
        return sourceModel() ? sourceModel()->columnCount(parent) : 0;
    
;

【讨论】:

好的,我明白了。然后我有两个问题: - 我如何在不创建代理索引的情况下实现我的目标?我想避免在代理模型中创建索引,因为不会有任何过滤/排序等,这将是原始模型索引的完全重复。 - 我不明白QSortFilterProxyModel 可以如何帮助我。我必须对data(..) 函数进行编码,由于上述原因,我还需要对index(...) 进行编码。 QSortFilterProxyModel 在我看来 QAbstractProxyModel 没有做什么? 您需要创建指向代理模型的新索引。 QSortFilterProxyMode 为您创建代理索引。 非常感谢,mapToSource 和 mapFromSource 对我来说简直就是恶魔之眼!这就像一个魅力! 不太正确:您的 mapToSource() 实现正在将 proxy.parent() 传递给源模型,该模型需要父模型的源索引。当然,这是可行的,因为您的父函数只是返回 QModelIndex() 并且您没有尝试支持树模型。 puetzk 是正确的。不仅mapToSource() 不正确,mapFromSource 也是!您将源索引source.parent() 传递给代理的index() 函数。正确完成的代理必须拒绝此类索引。查看QIdentityProxyModel 以查看必要的前置条件检查。

以上是关于在 QT 中,链接模型无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

带有导航组件的 Android 深层链接无法按预期工作

在 ionic 3 中,branch.io deeplink 无法按预期工作

SwiftUI PageView iOS 13 - 导航链接未按预期工作

新的拖放机制在 Qt-Quick (Qt 5.3) 中无法按预期工作

使用QWebEngine在同一窗口中打开任何链接(甚至_blank)

在构建脚本中使用 util.promisfy 无法按预期工作