【问题标题】:QWidget update events but no visual updateQWidget 更新事件但没有视觉更新
【发布时间】:2012-06-15 08:22:27
【问题描述】:

在 Mint Linux 12 上使用 Qt4.8,我实现了一个包含 QTableView 的简单窗口来显示模型的内容。模型数据不断更新(日志消息),dataChanged() 信号定期发出(即每 100 毫秒)。

我看到的问题是桌面上的视觉更新卡顿。

我在计算updateRequest 类型事件的窗口上安装了一个事件过滤器,这应该会触发小部件重绘(也在子小部件上,即tableView)。它们之间的平均时间约为 170 毫秒,标准偏差约为 90 毫秒(我猜这是相当大的)。然而,感知到的视觉更新率仅为每秒两到三倍,我想知道为什么。似乎并非所有updateRequest 事件都会触发小部件重绘或窗口系统会吞下视觉更新。

作为第二个测试,我通过每 100 毫秒调用一次 repaintupdate 来强制窗口自我更新。使用repaint,我看到updateRequest 类型的事件相应增加,并且差距的标准偏差减小;使用update,数量没有增加。然而,在这两种情况下,感知更新率都只有适度的增长。

另外:有没有一种很好的方法可以测量一个小部件实际上重新绘制的频率,而不必重载其paintEvent 处理程序?也许来自QTest 的东西?


更新:我扩展了我的事件过滤器来捕获paintEvent-type 事件。与> 1000 个updateRequest 类型的事件相比,这些事件只有一位数。

【问题讨论】:

    标签: c++ qt qwidget qtableview


    【解决方案1】:

    您应该检测事件调度程序的aboutToBlock()awake() 信号,并使用QElapsedTimer 测量它们之间的时间。当前线程的事件调度器实例由静态QAbstractEventDispatcher::instance()返回。

    如果事件循环在您的时间测量窗口的一小部分时间内处于休眠状态,则意味着 GUI 线程中发生了太多事情。您可以计算事件循环在最后一秒内休眠了多长时间。如果低于 10%,您可能会遇到更新缓慢之类的情况。请记住,更新事件与Qt::LowEventPriority 一起排队。它们将被标准排队信号和几乎所有其他事件抢占。

    【讨论】:

    • 好主意!我目前在项目方面的日程安排很紧,所以需要几天的时间来测试这个。我认为这应该让我对负载有一个很好的了解,但我实际上计算了到达我的小部件的 updateRequest 事件,并且这些事件比感知的更新速率更接近(平均而言)。
    • 计数没问题,但它并没有告诉您任何有关潜在问题的信息。它只是告诉您存在问题,而且您无需编写任何代码即可明显注意到它:)
    【解决方案2】:

    QApplication::compressEvent 丢弃 QEvent::UpdateRequest,如果已经有一个未处理。因此,如果事件被丢弃,即使 repaint(s) 也可以立即返回而无需绘制。您可以通过覆盖compressEvent 来检查您的updateRequest 事件是否被丢弃。

    【讨论】:

    • 我知道压缩,但这不是在某处的主事件循环/QApplication 中完成的吗?我认为如果 updateRequest 到达一个小部件,这应该已经完成​​了。
    • 你是对的,压缩是在EventLoop中完成的。我误解了,你在哪里计算事件。是的,如果事件到达小部件,则压缩已经完成。所以,忽略我的回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多