草庐IT

c++ - 模型更新量大的场景如何处理UI无响应

coder 2024-02-12 原文

我们使用的是 Qt 4.8.2,我们有一个模型/ View 设计(特别是 QAbstractItemModel 和 QTreeview 的子类)。模型/ TreeView 遵循 View 驱动模型的典型理念 - 在用户展开相应的 TreeView 节点之前,我们不会填充模型。

一旦节点展开且数据可见,它就会受到工作(非 UI)线程中发生的显示更新的影响。现在,当工作线程产生可能影响 TreeView 的更改时,它会发出一个“更改”信号,该信号映射到我们模型中的一个插槽。

问题是这些变化信号有时会以很高的频率发出(例如,每秒 1500 个事件),但它们可能适用于 TreeView 当前显示的内容(因此可以忽略)。发生这种情况时,UI 线程变得无响应,因为(我假设)所有信号都在排队,并且 UI 线程必须先处理它们,然后才能恢复响应用户交互。

响应更改信号所需的时间非常短,但 UI 线程似乎只是在一小段延迟后“吃掉”信号 - 大概是为了避免过度更新导致屏幕闪烁或其他烦恼。

结果是 UI 保持卡住 5 或 6 秒,在此期间 CPU 事件非常低(可能是因为信号传入速度足够快,处理程序仍在等待操作中断);一旦所有信号排队,线程最终会消耗队列中的工作并在几毫秒内解决它。

对此我有几点看法:

  1. 是否有一些设置可以提高 UI 线程处理传入信号的积极性?

  2. 在单独的线程中管理模型的更新完全可行吗?我的直觉是说不——Qt 机器似乎过于依赖模型的独占所有权,并且在其访问周围放置适当的锁保护会很复杂,并且违反了插槽/信号范例的全部要点。

  3. 我可以想出更复杂的方案来在辅助线程中处理此信号;例如,UI 可以维护一个单独的多线程可见(非模型)数据结构,可以查询该数据结构以确定是否需要发送更改信号。类似地,我可以维护工作线程使用的单独队列,我可以在其中将更改事件批量化为单个信号(例如,我可以每秒传送不超过两次)。但是,对于我认为在 Qt UI 编程领域中一定不会完全不常见的问题,这些方法让我觉得有点复杂。

最佳答案

我们有一个类似的应用程序,对基础数据进行了大量更新。问题归结为:
每秒 1500 次更新将导致 GUI 发生多少变化?
如果答案是少于 6 次更改,则模型每秒应仅发出 6 次数据更改。如果是这种情况,当底层数据更改时,检查此更改是否会更改 GUI,仅在必要时从模型发出数据更改信号。
如果答案是每秒会有超过 6 个 gui 变化,我们得到的答案是没有人可以看到每秒超过 3 个变化。底层数据更改根本不应该更新 GUI。使用一个250毫秒的定时器,在定时器事件中,检查需要更新的单元格,并进行更新。

关于c++ - 模型更新量大的场景如何处理UI无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22668333/

有关c++ - 模型更新量大的场景如何处理UI无响应的更多相关文章

  1. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  2. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  3. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  4. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  5. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  6. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  9. ruby-on-rails - 使用 rails 4 设计而不更新用户 - 2

    我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它​​不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数

  10. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

随机推荐