众所周知,QWidget::paintEvent
当小部件变为可见或基本窗口中的任何事件发生时会自动触发。如果我只想paintEvent
响应 发布,我应该怎么做update()
?
1 回答
paintEvent
每当需要绘制小部件时,不发出a 是没有意义的。您要求这样一个选项的理由意味着您正在尝试以不应该使用的方式使用 Qt API。我还不能完全想象一个特定的设计会导致你这样使用,对此感到抱歉。
所以,我唯一能告诉你的是你将如何使用update()
. 处理小部件更新的惯用方式如下:
小部件使用的数据源已更新。例如,更改了影响可见内容的文本或某些变量。通常,此数据是小部件的 Q_PROPERTY。setter 函数正在更新存储值和调用的成员变量
update()
。setter 不应该执行任何昂贵的计算——它们应该被推迟到绘制事件。如果在事件循环有机会运行之前多次更改属性,则更新事件会合并。在内部,调用 会
update()
导致将事件发布到 GUI 线程的事件队列。如果给定小部件的队列中已经存在更新事件,则这些事件将被合并。保留以下不变量:在任何给定时间,事件队列中的任何特定小部件都只能有一个更新事件。当控件返回事件循环时,更新事件被分派到小部件,最终调用您的
QWidget::paintEvent(...)
. 这个实现应该进行必要的计算来绘制小部件,并进行实际的绘制。如果计算范围很广,则应将它们归为工作线程。
例子
假设应用程序正在从串行端口接收数据,建模为 a QIODevice
(aQSerialPort
为 one)。您可以执行以下操作:
将 Connect
QIODevice
的readyRead
信号连接到解析器中的插槽QObject
。插槽接收并解析数据。然后它发出一个带有处理过的数据的信号(例如,一个浮点值向量)。此信号连接到
newData
小部件中的插槽。newData
插槽按原样将数据添加到队列中,并安排一个update()
. 如果您使用 Qt 的数据结构,或者如果您的数据类以它们为模型并使用写时复制的隐式共享,这将非常快。出
update()
列所有数据集并绘制它们。该QWidget::scroll()
方法对于滚动绘图很方便。