1
votes

I have a QTableView whose data model is a class derived from QSortFilterProxyModel that I have created myself. In this class we reimplemented the method filterAcceptsRow to be able to filter the data of the table according to several criteria. I can also sort the table by any of the fields in it.

The problem arises when the user clicks the "Create" button, which creates a new empty row in the table. If I have a filter applied, the empty row does not appear because it does not meet this filter, which I do not want to happen because the user has to start to edit their data obligatorily.

Also, when I have the table ordered by a field, when I add the empty row, it automatically positions itself in the position that it plays according to the sorting criteria, which is not desirable because I want it always to be in the first position.

Any idea how you can fix this problem?

1
You might temporary disable sorting with QTableView::setSortingEnabled(false) and enable it latter.vahancho

1 Answers

1
votes

I would try the following:

  1. Add another column to the model: "New item". The column would contain a boolean flag indicating whether the item is new i.e. it has just been added by the user. Since this column is purely for internal purposes, it won't be displayed by the view e.g. when you set up the view, you'd need to call setColumnHidden method on the view for this column.
  2. Make "Create" button set the value in this column to true for the new item added to the model.
  3. Adjust the sort method of the model (being the override of QSortFilterProxyModel's method) to always favour the items with the "New item" flag set to true, regardless of other sorting criteria.
  4. Create a custom delegate for the view (if you don't have one already) which would subclass QStyledItemDelegate and reimplement setModelData method in a very simple way:

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

    Here you let the QStyledItemDelegate do its thing inserting the editor's data into the model but then you immediately set to false the "New item" flag for this item thus indicating that user has finished its creation and from now on the item should be sorted using the conventional sorting criteria.

    In the ideal world you should also consider the possibility of cancelling the item creation. For example, if "Create" button was pressed and the editor for the new row was opened but user entered nothing and hit Enter, you should recognize that inside the delegate's setModelData and instead of inserting the empty string into the model simply remove the item from the model.