Solved 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.