Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QSortFilterProxyModel and strange interaction with hideColumn of a QTableView



  • Hello all, I am experiencing a really weird behaviour in my application (Qt 5.15.1 - Widgets).

    I have a QSqlRelationalTableModel that maps to a table in an sqlite database. This model is passed to a QSortFilterProxyModel for simple filtering and sorting, I apply the filter with setFilterRegularExpression. The relevant code is this:

    // Model for the slits
        m_model_slits = new SlitsQSqlRelationalTableModel( this );
        
        m_model_slits->setTable( "slits" );
        m_model_slits->setEditStrategy( QSqlRelationalTableModel::OnManualSubmit );
        m_model_slits->setRelation( m_model_slits->fieldIndex( "lot_id" ), QSqlRelation( "lots", "id", "id" ) );
        m_model_slits->select();
        
        m_proxy_slits = new QSortFilterProxyModel( this );
        
        m_proxy_slits->setSourceModel( m_model_slits );
        m_proxy_slits->sort( m_model_slits->fieldIndex( "serial" ) );
        m_proxy_slits->setFilterKeyColumn( m_model_slits->fieldIndex( "lots_id_2" ) );
        
        ui->wizard_serial_list->setModel( m_proxy_slits );
        ui->wizard_serial_list->setItemDelegateForColumn( m_model_slits->fieldIndex( "outcome" ), new OutcomeItemDelegate( this ) );
        // TODO: for some reason, hiding the id column will break the filtering. Should be investigated further
    //    ui->wizard_serial_list->hideColumn( m_model_slits->fieldIndex( "id" ) );
        ui->wizard_serial_list->hideColumn( m_model_slits->fieldIndex( "lots_id_2" ) );
    

    SlitsQSqlRelationalTableModel is a really simple modification to disable editing in most columns:

    class SlitsQSqlRelationalTableModel : public QSqlRelationalTableModel
    {
        Q_OBJECT
        
    public:
        explicit SlitsQSqlRelationalTableModel( QObject * p_parent = nullptr, const QSqlDatabase & p_database = QSqlDatabase() );
        
    private:
        Qt::ItemFlags flags( const QModelIndex & p_index ) const override;
    };
    
    SlitsQSqlRelationalTableModel::SlitsQSqlRelationalTableModel( QObject * p_parent, const QSqlDatabase & p_database )
        : QSqlRelationalTableModel( p_parent, p_database )
    {}
    
    
    Qt::ItemFlags SlitsQSqlRelationalTableModel::flags( const QModelIndex & p_index ) const
    {
        // Get original flags
        Qt::ItemFlags flags = QSqlTableModel::flags( p_index );
        
        // Ensure no edit flags on column that should be read only
        if ( p_index.column() != fieldIndex( "notes" ) )
        {
            flags &= ~Qt::ItemIsEditable;
        }
        
        // Return flags
        return flags;
    }
    

    Now, in the table view I don't like to see the ID column because it's irrelevant to the operator. But if I hide it, i get only partials results from the model! If I keep it shown, than I get all results. It does not make any sense to me.
    So: leaving the filter absolutely unchanged, I got different results showing or hiding the ID column from the view.

    Any idea?
    Thanks a lot.

    Ilario



  • @Ilaro said in QSortFilterProxyModel and strange interaction with hideColumn of a QTableView:

    Any idea?

    My guess: I think you are talking about hiding the column which is the one mapped for foreign key in the relation, is that right? If so, maybe there is an issue about that? If you hide a column which has nothing to do with the relation does it work better?



  • hiding the id column will break the filtering

    I struggle to see how given the proxy and the view live completely independent lives (i.e. when the proxy filters it doesn't know if the column is hidden or not)

    Could you share the code that you use to apply the filter?


Log in to reply