2017-06-21 72 views
0

我有一个QTableView,其数据模型是从我自己创建的QSortFilterProxyModel派生的类。在这个类中,我们重新实现了方法filterAcceptsRow,以便能够根据几个标准过滤表中的数据。我也可以通过其中的任何字段对表格进行排序。使用QSortFilterProxyModel添加新行

当用户单击“创建”按钮时会出现问题,该按钮将在表中创建一个新的空行。如果我应用了过滤器,则不会显示空行,因为它不符合此过滤器,我不希望这样做,因为用户必须开始强制编辑其数据。当我添加空行时,它自动根据排序标准将它自己放在它播放的位置,这是不可取的,因为我希望它始终是在第一个位置。

任何想法如何解决这个问题?

+0

您可能会临时禁用使用QTableView :: setSortingEnabled(false)进行排序并启用后者。 – vahancho

回答

0

我会尝试以下方法:

  1. 添加另一列到模型:“新项目”。该列将包含一个布尔标志,指示该项目是否是新的,即它刚刚被用户添加。由于该列纯粹是为了内部目的,因此它不会被视图显示,例如,当您设置视图时,您需要在此列的视图上调用setColumnHidden方法。
  2. 使用“创建”按钮将此列中的值设置为true以添加到模型中的新项目。
  3. 调整模型的sort方法(即覆盖QSortFilterProxyModel的方法)始终支持将“新项目”标志设置为true的项目,而不考虑其他排序标准。
  4. 创建一个自定义委托的视图(如果你没有的话),这将继承QStyledItemDelegate并以非常简单的方式重新实现setModelData方法:

    void MyItemDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) 
    { 
        QStyledItemDelegate::setModelData(editor, model, index); 
    
        MyModel * myModel = qobject_cast<MyModel*>(model); 
        myModel->clearNewFlagFromItem(index); 
    } 
    

    在这里,你让QStyledItemDelegate做它的事将编辑器的数据插入到模型中,但是您立即将false设置为该项目的“新项目”标志,从而表示该用户已完成其创建,并且从现在开始应该使用传统分类标准对该项目进行排序。

    在理想的世界中,您还应该考虑取消物品创建的可能性。例如,如果按下“创建”按钮并且新行的编辑器已打开,但用户没有输入任何内容并按下Enter,则应该认识到代理的内部setModelData并不是将空字符串插入模型中,而是将该项目从该模型。