I have problem with loading QAbstractListModel items to QML GridView asynchronously. When I execute method that loads items to model I have to wait for every item is loaded. How can I get items dynamically (i.e. one by one)?
I have pretty big model objects with 17 fields (QString and QStringList's). Objects are contained in custom model:
class MyListModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ListItemRole {
IdRole = Qt::UserRole,
VisualIndexRole,
NameRole,
...
};
MyListModel(QObject *parent = 0)
: QAbstractListModel(parent)
{
}
int rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_data.size();
}
QVariant data(const QModelIndex &index, int role) const
{
if( !index.isValid() || index.row() >= m_data.size() || index.row() < 0)
return QVariant();
switch(role) {
case NameRole:
return QVariant(m_data.at(index.row())->name());
...
(rest of the roles)
...
}
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[IdRole] = "folderName";
...
return roles;
}
private:
QList<Item*> m_data;
}
I'm inserting items to model by append method:
void append(Item *item)
{
beginInsertRows(QModelIndex(), m_data.size(), m_data.size());
m_data.append(item);
endInsertRows();
}
Items is created in loop in other function. This function loads data from 3 JSON files. It takes about 2 seconds to load 50 items.
On top of this list model, there are two QSortFilterProxyModel's responsible for sorting and filtering view. Filtering model is registered as QML type and used in GridView.
What I tried:
- Use
QtConcurrent::run()method for function that create item - FAIL ( view not refreshed after every item) - Make
QThreadfor every list item, and load it withWorkerclass - FAIL ( crashes and strange behavior of application, i.e. empty items, empty spaces between delegates and - as in the first point - not async) - Move model to
QThreadand use item creating loop inWorkerclass - Partiall Success ( when I useQCoreApplication::processEvents(QEventLoop::AllEvents,100);as a sleep function I could get one by one items, but there is heavy performance issues and - as i read - it is not good approach)
Is there any possible workarounds for my problem?