BingoTogo
BingoTogo

Reputation: 5

Adding many data in QListView without "not responding"

for a project I need to integrate a lot of data in a QListView, I get the data from a QThread and store it in a QMap<QString, QString>, until then I have no problem of crash or freeze. But when in my QThread I browse my QMap to call for each element the function that will add the QString in the QListView, then I have a freeze. I searched a lot but I didn't find or understand how to do it. I add you a part of the simplified code to show you my problem :

exemple.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QPushButton>
#include <QListView>
#include <QStandardItemModel>
#include <QDebug>
#include <QThread>

#include "mythread.h"

class exemple : public QMainWindow
{
    Q_OBJECT
public:
    explicit exemple(QWidget *parent = nullptr);

private:
    QPushButton *btn_start;
    QListView *lv_file;
    QMap<QString, QString> myMap;
    MyThread *m_thread;
    QStandardItemModel *model;

public slots:
    void addFileInformation(QString, QString);
    void startShow();

private slots:
    void startThread();

};

#endif // MAINWINDOW_H

mythread.h

#ifndef MYTHREAD_H
#define MYTHREAD_H

#include <QThread>
#include <QDebug>
#include <QDirIterator>

class MyThread : public QThread
{
    Q_OBJECT
public:
    explicit MyThread(QObject *parent);
    void run();

signals:
    void addFileInformation(QString, QString);
    void startShow();

};

#endif // MYTHREAD_H

exemple.cpp

#include "exemple.h"

exemple::exemple(QWidget *parent) : QMainWindow(parent)
{
    setFixedSize(750,750);

    btn_start = new QPushButton("start", this);
    btn_start->setGeometry(50, 40, 150, 30);
    btn_start->setCursor(Qt::PointingHandCursor);

    lv_file = new QListView(this);
    lv_file->setGeometry(50, 100, 600, 500);

    m_thread = new MyThread(this);
    model = new QStandardItemModel(this);

    lv_file->setModel(model);

    connect(btn_start, SIGNAL(clicked()), this, SLOT(startThread()));
    connect(m_thread, SIGNAL(addFileInformation(QString, QString)),this, SLOT(addFileInformation(QString, QString)));
    connect(m_thread, SIGNAL(startShow()),this, SLOT(startShow()));
}

void exemple::startThread(){
    m_thread->start();
}

void exemple::addFileInformation(QString param1, QString param2)
{
    myMap.insert(param1, param2);
}

void exemple::startShow(){

    for (int i = 0; i < myMap.size(); i++){
        model->appendRow(new QStandardItem(myMap.keys()[i]));
    }
}

In this example it would be when the thread calls the startShow slot that my freeze appears.

I understand that I'm not in the thread anymore and that's the reason of the freeze but I have the same problem if instead of adding information to a QMap on "exemple" as I do here, the addFileInformation slot of example.cpp displayed directly the information. Like this:

exemple.cpp

void exemple::addFileInformation(QString param1, QString param2)
{
    model->appendRow(new QStandardItem(param1));
}

If you have a solution, a track or a link to do this without freezing I'm interested :)

If I'm not clear don't hesitate to ask me to explain it again, thanks to those who will take their time to help me.

Upvotes: 0

Views: 320

Answers (3)

user15422194
user15422194

Reputation: 1

You must use a signal to send your mapdata to the ui thread and append a row in your thread, not just append a row directly in your thread.

i have review u code carefully,and maybe u should try this way:

void exemple::startShow()

    { 
    QList<QStandardItem*> itemList; 
    for (int i = 0; i < myMap.size(); i++)
    { itemList<<(new QStandardItem(myMap.keys()[i])); 
    } 
    model->appendRow(itemList); 
    } 

Upvotes: 0

Joseph Larson
Joseph Larson

Reputation: 9058

If your dataset is large, you probably need to implement your own model that uses the data in the fashion you're storing it. Models in Qt are tricky, but once you've done a few they begin to make sense.

I've got an example on my github: https://github.com/jplflyer/qt-TreeViewDemo. It's probably not perfect. I wrote it while trying to figure out how to write it. This is for QTreeView, but QListView won't be that different.

I also have a generic version here: https://github.com/jplflyer/Git-Dashboard. Look down into the tree for GenericItemModel. It's a template and is kind of cool, actually. It also may not be fully featured, but it might help.

Upvotes: 1

mugiseyebrows
mugiseyebrows

Reputation: 4698

You can try to unset model from view lv_file->setModel(nullptr); to get rid of unnecessary view refreshes (after each row insert), change model and set it back to view.

Upvotes: 0

Related Questions