Important: Please read the Qt Code of Conduct -

[SOLVED] QTableView reset View

  • Hi,
    I read in some data from some log-files and save them in a QAbstractTableModel.
    I have put a QSortFilterProxyModel between the model and the QTableView.

    My Question now is that when I set the filter options for the proxy-model and want to show the new view with the filter. What is than the best way to reset the filter?

    currently I use the reset() function from the QTableView.

    And when I try to look if the row is hidden with isRowHidden() it always returns false, but the rows are not shown in the view.

  • If possible, use
    void QAbstractItemModel::beginResetModel () [protected]
    in your model. This will safely signal all connected View to "reload" data from the model. Because the models are loaded, they will be re read!
    Do not use reset() directly, it is a possible cause for undefined behavior!
    Read docs of QAbstractItemModel!

  • Moderators

    [quote author="Tecnova" date="1385390599"]
    My Question now is that when I set the filter options for the proxy-model and want to show the new view with the filter. What is than the best way to reset the filter?
    I assume you use QSortFilterProxyModel?
    If so just use one of these methods:
    void setFilterRegExp(const QString &pattern);
    void setFilterWildcard(const QString &pattern);
    void setFilterFixedString(const QString &pattern);
    void invalidate();

  • thx for the fast reply.

    yes I'm using a QSortFilterProxyModel.

    When I use invalidate() the view gets updated.
    But I still get false from
    @bool QTableView::isRowHidden(int row) const@

    I do that because, I only show 500 rows in one view and when I use a filter on that view sometimes only 10 or less rows are shown. Now I want to get so much new shown rows until I have 500 rows in the current view

    MyTableView widget = (MyTableView) ui->tabWidget->widget(ui->tabWidget->currentIndex()); //get the Table from the current tab

    Filter *filter =>tabWidget->currentIndex()); // get the QSortFilterProxyModel from the current tab

    filter->invalidate(); //reset the view

    for(int r = filter->getMinrow(); r < filter->getMaxrow(); r++)
    qDebug() << "row :" << r << " is " << widget->isRowHidden(r) << "\n";
    if(!widget->isRowHidden(r)) //when row is not hidden inc rowCounter
    if(this->rowCounter < 500) //when less than 500 rows are shown
    //update the shown row range by +500
    if(filter->getMaxrow() >= filter->sourceModel()->rowCount())
    else filter->setMaxrow(filter->getMaxrow()+500);
    showFilter(); //update view again

  • Moderators

    isRowHidden() just checks if you have set the row hidden in the vertical headerview. This requires to call setRowHidden() first.
    In your filter method just filter accept the filtered rows until you have reached the max row count instead the way you are currently doing it.

  • I tried that too, but
    @bool QSortFilterProxyModel::filterAcceptsRow(int sourcerow, const QModelIndex &sourceparent) const@

    is const so I can't change attributes in the function.

    My filter currently looks like:

    @bool Filter::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    int today = QDate::currentDate().year()0;
    if(sourceRow >= minrow && sourceRow <= maxrow)
    QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent), //Date
    index1 = sourceModel()->index(sourceRow, 1, sourceParent), //Time
    index2 = sourceModel()->index(sourceRow, 2, sourceParent), //Source
    index3 = sourceModel()->index(sourceRow, 4, sourceParent), //Data0
    index4 = sourceModel()->index(sourceRow, 8, sourceParent); //Event/Error

        QStringList timevalues = sourceModel()->data(index1).toString().split(':');   //split the time string from the filter to houres, minutes and seconds
        QString  h =,
                 m =,
                 s =;
        //make the time string to a time      
        QTime timer(h.toInt(), m.toInt(), s.toInt()); 

    //split the time string from the filter to year, month and day
    timevalues = sourceModel()->data(index0).toString().split('/');
    h =, //year
    m =, //month
    s =; //day

        if(h.toInt() <= today && h.size() == 2)
            h.insert(0, "20");
        else h.insert(0, "19");

    //make the time string to a time
    QDate dater(h.toInt(), m.toInt(), s.toInt());

    //now check if the rows data fit with the filter
    return timeInRange(timer)
    && dateInRange(dater)
    && sourcecheck(index2)
    && data0check(index3)
    && sourceModel()->data(index4).toString().contains(this->rxtype);
    else return false;

    and I can't call a not const function in it that counts the hidden rows

  • Moderators

    why do you need to change attributes?!
    You are just reading the max count. When you set the max count from externally do also an invalidate of the filter.
    And if you really have to change the attribute from the inside of a const method declare it as "mutable".

  • ah OK didn't know that.
    thanks a lot.
    it works now :)

Log in to reply