Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[quick] Fix slow value relation widget
If value relation widget in qgis_quick was populated with lots of items, it was getting very slow - this was due to the use of ListModel QML item. The fix introduces a c++ based model which is fast to populate and look up values in the list.
- Loading branch information
Showing
7 changed files
with
149 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/*************************************************************************** | ||
qgsquickvaluerelationlistmodel.cpp | ||
-------------------------------------- | ||
Date : March 2020 | ||
Copyright : (C) 2020 by Martin Dobias | ||
Email : wonder dot sk at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#include "qgsquickvaluerelationlistmodel.h" | ||
|
||
#include "qgslogger.h" | ||
|
||
|
||
QgsQuickValueRelationListModel::QgsQuickValueRelationListModel( QObject *parent ) | ||
: QAbstractListModel( parent ) | ||
{ | ||
} | ||
|
||
void QgsQuickValueRelationListModel::populate( const QVariantMap &config, const QgsFeature &formFeature ) | ||
{ | ||
beginResetModel(); | ||
mCache = QgsValueRelationFieldFormatter::createCache( config, formFeature ); | ||
endResetModel(); | ||
} | ||
|
||
QVariant QgsQuickValueRelationListModel::keyForRow( int row ) const | ||
{ | ||
if ( row < 0 || row >= mCache.count() ) | ||
{ | ||
QgsDebugMsg( "keyForRow: access outside of range " + QString::number( row ) ); | ||
return QVariant(); | ||
} | ||
return mCache[row].key; | ||
} | ||
|
||
int QgsQuickValueRelationListModel::rowForKey( const QVariant &key ) const | ||
{ | ||
for ( int i = 0; i < mCache.count(); ++i ) | ||
{ | ||
if ( mCache[i].key == key ) | ||
return i; | ||
} | ||
QgsDebugMsg( "rowForKey: key not found: " + key.toString() ); | ||
return -1; | ||
} | ||
|
||
int QgsQuickValueRelationListModel::rowCount( const QModelIndex & ) const | ||
{ | ||
return mCache.count(); | ||
} | ||
|
||
QVariant QgsQuickValueRelationListModel::data( const QModelIndex &index, int role ) const | ||
{ | ||
if ( !index.isValid() ) | ||
return QVariant(); | ||
|
||
int row = index.row(); | ||
if ( row < 0 || row >= mCache.count() ) | ||
return QVariant(); | ||
|
||
if ( role == Qt::DisplayRole ) | ||
return mCache[row].value; | ||
|
||
return QVariant(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/*************************************************************************** | ||
qgsquickvaluerelationlistmodel.h | ||
-------------------------------------- | ||
Date : March 2020 | ||
Copyright : (C) 2020 by Martin Dobias | ||
Email : wonder dot sk at gmail dot com | ||
*************************************************************************** | ||
* * | ||
* This program is free software; you can redistribute it and/or modify * | ||
* it under the terms of the GNU General Public License as published by * | ||
* the Free Software Foundation; either version 2 of the License, or * | ||
* (at your option) any later version. * | ||
* * | ||
***************************************************************************/ | ||
|
||
#ifndef QGSQUICKVALUERELATIONLISTMODEL_H | ||
#define QGSQUICKVALUERELATIONLISTMODEL_H | ||
|
||
#include "qgis_quick.h" | ||
|
||
#include <QAbstractListModel> | ||
|
||
#include "qgsvaluerelationfieldformatter.h" | ||
|
||
/** | ||
* \ingroup quick | ||
* List model for combo box in Value Relation widget. | ||
* The model keeps a list of key-value pairs fetched from a vector layer. "Values" are the human readable | ||
* descriptions (QString), "keys" are unique identifiers of items (QVariant). | ||
* | ||
* \note QML Type: ValueRelationListModel | ||
* | ||
* \since QGIS 3.14 | ||
*/ | ||
class QUICK_EXPORT QgsQuickValueRelationListModel : public QAbstractListModel | ||
{ | ||
Q_OBJECT | ||
public: | ||
//! Construct an empty list model | ||
QgsQuickValueRelationListModel( QObject *parent = nullptr ); | ||
|
||
//! Populate the model from vector layer's widget configuration | ||
Q_INVOKABLE void populate( const QVariantMap &config, const QgsFeature &formFeature = QgsFeature() ); | ||
|
||
//! Returns key for the given rown number (invalid variant if outside of the valid range) | ||
Q_INVOKABLE QVariant keyForRow( int row ) const; | ||
//! Returns row number | ||
Q_INVOKABLE int rowForKey( const QVariant &key ) const; | ||
|
||
int rowCount( const QModelIndex & ) const override; | ||
QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const override; | ||
|
||
private: | ||
QgsValueRelationFieldFormatter::ValueRelationCache mCache; | ||
}; | ||
|
||
#endif // QGSQUICKVALUERELATIONLISTMODEL_H |