从聚合线程更新 QListView 使 GUI 冻结

发布于 2024-12-24 22:09:10 字数 775 浏览 1 评论 0原文

在一个简单的应用程序中,我有一个 Mainwindow,其中包含使用 QAbstractListModelQListView

当我启动应用程序时,我使用线程工作线程启动一个线程,该线程从外部 Web 服务获取数据记录,每个线程获取 10-20 条记录 迭代。

问题:

在从大 while 循环中的线程工作线程启动的 HttpAggrigator 类中,该循环迭代每个返回的记录,我向另一个名为 ViewControler 的类发出信号,其工作是填充QListView模型。

在这一部分中,我的窗口只是冻结,直到所有项目都在列表视图中设置。

我使用名为“Sleepy”的分析工具进行了检查,确实,设置项目的 ViewControler 方法导致速度变慢。

流程:

  • MainWindow ->启动 HttpAggrigator(在不同的线程中)。
  • HttpAggrigator ->获取记录->开始迭代它们(以填充数据对象)。
  • HttpAggrigator ->在每次记录迭代时向 ViewControler 发出信号,以将项目构建到 MainWindow QListView 中。

添加项目时如何防止 GUI 冻结和变慢?

In a simple application, I have a Mainwindow containing a QListView using a QAbstractListModel.

When I start the application I start a single thread using a thread worker that gets data records from an external web service, it gets 10-20 records each
Iteration.

Problem:

In the HttpAggrigator class that started from the thread worker in the big while loop that iterates on each returned record, I emit a signal to another class called ViewControler, and its job is to populate the QListView model.

In this part, my window just freezes until all the items are set in the listview.

I checked with the profiling tool called “Sleepy” and indeed, the ViewControler method that sets the items is causing the slow down.

The flow:

  • MainWindow -> starts HttpAggrigator (in a different thread ).
  • HttpAggrigator -> gets records -> starts to iterate them ( to fill data objects ).
  • HttpAggrigator -> emits a signal to ViewControler on each record iteration to build item into MainWindow QListView.

How can I prevent the GUI freeze and slow down when adding items?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

别靠近我心 2024-12-31 22:09:10

每次将项目添加到模型中时,都会导致视图重新绘制自身。您应该将项目聚合到一个列表中并立即将其插入模型中。您将有 1 次重画,而不是 n 次重画

使用这样的方法一次处理多个项目

void LostModel::addItems(QList<MyItem *> items)
{
    if(items.size())
    {
        int begin = MyItemList.size();

        beginInsertRows(QModelIndex(), begin, begin + items.size() - 1);
        MyItemList.append(items);
        endInsertRows();
    }
}

Everytime you're adding item to model you cause view to repaint itself. You should agregate items into one list and insert it into model at once. You will have 1 repaint instead of n repaints

Use method like this with more than one item at a time

void LostModel::addItems(QList<MyItem *> items)
{
    if(items.size())
    {
        int begin = MyItemList.size();

        beginInsertRows(QModelIndex(), begin, begin + items.size() - 1);
        MyItemList.append(items);
        endInsertRows();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文