在Qt中如何对QModelIndex的直接子索引进行排序

时间:2012-05-23 16:47:15

标签: qt sorting qabstractitemmodel qmodelindex qsortfilterproxymodel

我正在编写一个使用Qt类来处理某些数据模型的C ++应用程序。为此,我继承自QAbstractItemModel

// the following is a class that represents the actual data used in my application
class EventFragment
{
....
private:
    qint32 address;
    QString memo;
    QDateTime dateCreated;
    QVector<EventFragment*> _children;
....
};

// the following is the model representation that used by my application to display the actual details to the user
class EventModel : public QAbstractItemModel
{
     Q_OBJECT
public:
     explicit EventModel (QObject *parent = 0);
....
private:
     // the following is the root item within the model - I use a tree-like presentation to show my data
     EventFragment* _rootFragment;
};

在某些时候我需要在我的应用程序中使用排序/过滤器选项,所以我还创建了一个继承自QSortFilterProxyModel

的类
class EventProxyModel : public QSortFilterProxyModel
{
     Q_OBJECT
public:
     explicit EventProxyModel (QObject *parent = 0);
...
public:
     // I had to add my custom implementation in the 'lessThan' method to achieve a
     // more complex sort logic (not just comparing the actual values but using
     // additional conditions to compare the two indexes)
     virtual bool lessThan ( const QModelIndex & left, const QModelIndex & right ) const;
...
};

为了实现排序,我使用了默认的QSortFilterProxyModel::sort()方法(我没有在我的代理模型类中重新实现它),并且它似乎有效。

但在某些时候,我注意到实际的QSortFilterProxyModel::sort()方法对整个模型进行了排序,我需要的是只对某个索引的直接子项进行排序。

我尝试重新实现sort()类的EventModel方法,但过了一段时间后,我意识到QSortFilterProxyModel::sort()根本没有提到它。另一方面,我不确定如何以安全的方式重新排列索引,以便显示模型的视图不会崩溃。

我认为必须有办法只对某个QModelIndex的直接孩子进行排序,但我还没有找到它。

是否有任何教程/示例演示了我的案例的可能解决方案,或者有关如何执行此操作的一些指导原则?

此致

1 个答案:

答案 0 :(得分:1)

如果你想要一个优化的解决方案,根本不对你不想排序的索引进行比较,我认为你必须重新构建你自己的QAbstractProxyModel,这是一项非常重要的任务。但是,如果您使用非优化解决方案,我会尝试这样做:

bool EventProxyModel::lessThan( const QModelIndex & left, const QModelIndex & right ) const {
    if ( left.parent() == isTheOneToSortChildrenFor ) {
        ...apply custom comparison
    } else {
        return left.row() < right.row();
    }
}

比较源中的行应该保留其他所有内容,然后将索引与特定父项一起保留原样。