Application crashes while adding rows in qml TableView



  • I have custom data model which inherits QAbstractTablemodel assigned to qml Tableview.
    Everything was working fine.

    But now I wanted searching and sorting feature in my tableview so I used SortFilterProxyModel for this. As I insert rows in my source model, application crashes. I am emitting proper signals viz, beginInsertRows() and endInsertRows(). Crash was not producible in debug mode.
    I have collected some stack trace of crash:

    0 QVariant::toString() const 0x68a461e6
    1 QSortFilterProxyModel::lessThan(QModelIndex const&, QModelIndex const&) const 0x689f3a21
    2 QSortFilterProxyModel::filterRole() const 0x689f4926
    3 QSortFilterProxyModel::filterRole() const 0x689f4e88
    4 QSortFilterProxyModel::setSortRole(int) 0x689f8ac6
    5 QSortFilterProxyModel::setSortRole(int) 0x689f8ce5
    6 QSortFilterProxyModel::qt_static_metacall(QObject *, QMetaObject::Call, int, void * *) 0x689fb70b
    7 QMetaObject::activate(QObject *, int, int, void * *) 0x68a351b5
    8 QAbstractItemModel::rowsInserted(QModelIndex const&, int, int, QAbstractItemModel::QPrivateSignal) 0x68a9c9d7
    9 QAbstractItemModel::endInsertRows() 0x689e2a39
    10 ?? 0x4b0c69
    11 ?? 0x4b230d
    12 ?? 0x48958f
    13 ?? 0x5649d2
    14 QMetaObject::activate(QObject *, int, int, void * *) 0x68a351b5
    15 ?? 0x56f9bd
    16 QMetaObject::activate(QObject *, int, int, void * *) 0x68a351b5
    17 ?? 0x570a4a
    18 ?? 0x5179c9
    19 ?? 0x5509cd
    ... <More>

    Can someone help?



  • @Ashu_9791 said in Application crashes while adding rows in qml TableView:

    Crash was not producible in debug mode

    Ouch...

    Let's try to narrow it down manually then.

    • try replacing your custom model with a QStandardItemModel (just a test one, you don't need to do much)
    • try removing the proxy and see if it works
    • try implementing the QSortFilterProxyModel on the c++ side and see if you get a debug mode crash there


  • @VRonin
    try removing the proxy and see if it works
    Yes. It works properly as earlier if I remove proxyModel.

    try implementing the QSortFilterProxyModel on the c++ side and see if you get a debug mode crash there
    I have custom implemented this. Here is the code for it:

    #include "sortfilterproxymodel.h"
    #include <QtDebug>
    #include <QtQml>
    
    SortFilterProxyModel::SortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
    {
        connect(this, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SIGNAL(countChanged()));
        connect(this, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SIGNAL(countChanged()));
    }
    
    int SortFilterProxyModel::count() const
    {
        return rowCount();
    }
    
    QObject *SortFilterProxyModel::source() const
    {
        return sourceModel();
    }
    
    void SortFilterProxyModel::setSource(QObject *source)
    {
        setSourceModel(qobject_cast<QAbstractItemModel *>(source));
    }
    
    QByteArray SortFilterProxyModel::sortRole() const
    {
        return roleNames().value(QSortFilterProxyModel::sortRole());
    }
    
    void SortFilterProxyModel::setSortRole(const QByteArray &role)
    {
        QSortFilterProxyModel::setSortRole(roleKey(role));
    }
    
    void SortFilterProxyModel::setSortOrder(Qt::SortOrder order)
    {
        QSortFilterProxyModel::sort(order);
    }
    
    QByteArray SortFilterProxyModel::filterRole() const
    {
        return roleNames().value(QSortFilterProxyModel::filterRole());
    }
    
    void SortFilterProxyModel::setFilterRole(const QByteArray &role)
    {
        QSortFilterProxyModel::setFilterRole(roleKey(role));
    }
    
    QString SortFilterProxyModel::filterString() const
    {
        return filterRegExp().pattern();
    }
    
    void SortFilterProxyModel::setFilterString(const QString &filter)
    {
        setFilterRegExp(QRegExp(filter, filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(filterSyntax())));
    }
    
    SortFilterProxyModel::FilterSyntax SortFilterProxyModel::filterSyntax() const
    {
        return static_cast<FilterSyntax>(filterRegExp().patternSyntax());
    }
    
    void SortFilterProxyModel::setFilterSyntax(SortFilterProxyModel::FilterSyntax syntax)
    {
        setFilterRegExp(QRegExp(filterString(), filterCaseSensitivity(), static_cast<QRegExp::PatternSyntax>(syntax)));
    }
    
    QJSValue SortFilterProxyModel::get(int idx) const
    {
        QJSEngine *engine = qmlEngine(this);
        QJSValue value = engine->newObject();
        if (idx >= 0 && idx < count()) {
            QHash<int, QByteArray> roles = roleNames();
            QHashIterator<int, QByteArray> it(roles);
            while (it.hasNext()) {
                it.next();
                value.setProperty(QString::fromUtf8(it.value()), data(index(idx, 0), it.key()).toString());
            }
        }
        return value;
    }
    
    int SortFilterProxyModel::roleKey(const QByteArray &role) const
    {
        QHash<int, QByteArray> roles = roleNames();
        QHashIterator<int, QByteArray> it(roles);
        while (it.hasNext()) {
            it.next();
            if (it.value() == role)
                return it.key();
        }
        return 0;
    }
    
    QHash<int, QByteArray> SortFilterProxyModel::roleNames() const
    {
        if (QAbstractItemModel *source = sourceModel())
            return source->roleNames();
        return QHash<int, QByteArray>();
    }
    
    bool SortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    {
        qDebug()<<"[SortProxyModel] Source Row "<<sourceRow;
        QRegExp rx = filterRegExp();
        if (rx.isEmpty())
            return true;
        QAbstractItemModel *model = sourceModel();
        if (filterRole().isEmpty()) {
            QHash<int, QByteArray> roles = roleNames();
            QHashIterator<int, QByteArray> it(roles);
            while (it.hasNext()) {
                it.next();
                QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
                QString key = model->data(sourceIndex, it.key()).toString();
                if (key.contains(rx))
                    return true;
            }
            return false;
        }
    
        QModelIndex sourceIndex = model->index(sourceRow, 0, sourceParent);
        if (!sourceIndex.isValid())
            return true;
        QString key = model->data(sourceIndex, roleKey(filterRole())).toString();
        return key.contains(rx);
    }
    
    int SortFilterProxyModel::getSourceIndex(int idx)
    {
        if (idx >= 0 && idx < count())
        {
            QModelIndex index2 = mapToSource(index(idx, 0));
            return index2.row();
        }
        return -1;
    }
    

    try replacing your custom model with a QStandardItemModel (just a test one, you don't need to do much)
    What I need to change in my code for this?



  • @Ashu_9791 said in Application crashes while adding rows in qml TableView:

    void SortFilterProxyModel::setSortOrder(Qt::SortOrder order)
    {
    QSortFilterProxyModel::sort(order);
    }

    that should be QSortFilterProxyModel::sort(sortColumn(),order);



  • @VRonin
    Thanks. That fix doesn't crash application.
    But it doesn't sort the table on column header click because I have not set sortColumn.
    How can I set sortColumn through my SortFilterProxyModel class?



  • @Ashu_9791 said in Application crashes while adding rows in qml TableView:

    How can I set sortColumn through my SortFilterProxyModel class?

    Just as you do the sort order.

    call QSortFilterProxyModel::sort(columnYouWantToSort,sortOrder())



  • This post is deleted!


  • @VRonin said in Application crashes while adding rows in qml TableView:

    @Ashu_9791 said in Application crashes while adding rows in qml TableView:

    How can I set sortColumn through my SortFilterProxyModel class?

    Just as you do the sort order.

    call QSortFilterProxyModel::sort(columnYouWantToSort,sortOrder())

    After setting sortColumn it crashed again.
    I think there is some problem with indexing after sorting which is making it crash. May be I am wrong.



  • The issue is fixed.
    I just took one local variable for sortColumn. Initializing with -1 doesn't crash the application.
    Thanks.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.