【问题标题】:Qtableview operations on filtered sets过滤集上的 Qtableview 操作
【发布时间】:2013-03-12 16:55:32
【问题描述】:

我有一个工作 Qtableview 自定义模型子类 QAbstractTableModel 和 QAbstractItemModel。

我有一个 Qlineedit,点击它会过滤视图:

// 模型.cpp setFilter(QString strFilter) 函数通过我的实习生 QList 搜索(此 Qlist 实际上附加到模型),如果找到匹配项,则:m_filterSet.insert(i);

这一切都很好。问题是,我对 tableview 进行了 CRUD 操作(插入行,删除行..),这也很好用!但是当从 filtered 集合中选择一行时,我需要以某种方式知道我的 QList 中的这个选定行究竟是来自过滤集合 (QSet) 的哪个位置。

ui.myView->selectionModel()->currentIndex().row();

obvious 为当前视图提供了错误的索引计数。

如何以某种方式从 QSet 中的选定行中提取值 (int)? 因为当我将此功能添加到模型时:

foreach (const int &value, m_filterSet)
        qDebug() << value;

已成功打印出所有 i 值,例如:3410、3411、3412(这些是我的客户 ID)

如果我可以为 Qset 中的选定行提取此 ID,我可以编写一个迭代我的实习生 QList 的函数,并找到一个匹配的,可以这么说:

if(m_Intern[i].nClientID == nId){   // nId = value inside Qset for selected row in view
    return nIdx;
}

【问题讨论】:

    标签: qt


    【解决方案1】:

    Qt 为您的问题提供了解决方案 - 只需使用 QSortFilterProxyModel。您需要:

    • 对其进行子类化并编写您自己的过滤函数 (filterAccpetsRow)
    • 通过过滤来代理您的原始模型
    • 将过滤模型附加到视图
    • 使用QSortFilterProxyModel::mapToSource() 在过滤模型和原始模型中的索引之间进行转换。

    这允许您使用一个源数据模型拥有多个视图,每个视图可能有不同的过滤器。

    【讨论】:

    • 您是否需要在原始视图代码中对currentIndex() 的每次调用都使用 mapToSource() 或者是否有更聪明的方法来映射索引?
    【解决方案2】:

    经过一段时间的思考,我解决了,我只需要在我的模型中实现另一个功能:

    int myClass::screenIndex2DataIndex(int nIdxScreen)
    {
       if(m_bUseFilter)
        {
            int nIdx =-1;
            for(int i=0;i<m_lstIntern.size();i++)
            {
                if(m_filterSet.contains(i))
                {
                    nIdx++;
                    if(nIdx == nIdxScreen){
                        return i;   
                    }
                }
            }
            return -1; //not found
        }
        else{
            return nIdxScreen;
        }
    }
    

    这样我可以在过滤视图中找到当前索引,它在我的实习生列表中。

    在此之后,很容易通过返回获得我的 nClientID:return m_lstIntern[idx].nClientId

    【讨论】:

    • 对于每个索引查找,平均而言,您的列表要经过一半的比较。如果您不想走 QSortFilterProxyModel 路线,则可以在构建将过滤索引映射到未过滤索引的过滤集时填充 QMap 。我猜这个需求取决于这个函数需要多久被调用一次。
    • 你是对的,但是我对模型视图编程和 Qt 整体来说是新手,因为这只是我在 C++/Qt 中工作的第二个更大的项目并且没有时间投资研究。但是,我的实现有效,解决了问题,并且在视图中的 4000 行上,过滤到最后添加的一些项目我没有注意到任何延迟,它相当即时。谢谢哥们,我已经给你点了。我应该检查你的遮阳篷是否被接受?
    • QSortFilterProxyModel::mapToSource 听起来更好并且有好处。但我现在不能倒退,需要向前推进..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多