微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 QListView 中添加许多数据而没有“无响应”

如何解决在 QListView 中添加许多数据而没有“无响应”

对于一个需要在QListView中整合大量数据的项目,我从QThread获取数据并将其存储在QMap中,直到那时我没有崩溃或冻结的问题。但是当在我的 QThread 中浏览我的 QMap 为每个元素调用将在 QListView 中添加 QString 的函数时,然后我冻结了。我搜索了很多,但我没有找到或不明白如何去做。我向您添加了一部分简化代码以向您展示我的问题:

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

示例.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)),SLOT(addFileinformation(QString,QString)));
    connect(m_thread,SIGNAL(startShow()),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]));
    }
}

在这个例子中,当线程调用 startShow 插槽时,我的冻结就会出现。

我知道我不再在线程中,这就是冻结的原因,但如果不是像我在这里那样向“示例”上的 QMap 添加信息,示例的 addFileinformation 插槽,我会遇到同样的问题。 cpp 直接显示信息。像这样:

示例.cpp

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

如果您有解决方案、曲目或链接可以在不冻结的情况下执行此操作,我很感兴趣:)

如果我不清楚,请不要犹豫,再次要求我解释,感谢那些愿意花时间帮助我的人。

解决方法

如果您的数据集很大,您可能需要实现自己的模型,以您存储数据的方式使用数据。 Qt 中的模型很棘手,但是一旦您完成了一些模型,它们就会开始变得有意义。

我的 github 上有一个示例:https://github.com/jplflyer/qt-TreeViewDemo。它可能并不完美。我在试图弄清楚如何编写它时写了它。这适用于 QTreeView,但 QListView 不会有什么不同。

我这里也有一个通用版本:https://github.com/jplflyer/Git-Dashboard。向下查看 GenericItemModel 的树。这是一个模板,实际上很酷。它也可能功能不全,但可能会有所帮助。

,

您可以尝试从视图 lv_file->setModel(nullptr); 中取消设置模型以摆脱不必要的视图刷新(每行插入后),更改模型并将其重新设置为视图。

,

您必须使用信号将您的地图数据发送到 ui 线程并在您的线程中追加一行,而不是直接在您的线程中追加一行。

我仔细检查了你的代码,也许你应该试试这种方式:

void exemple::startShow()

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。