Qt自定义控件更新的开销很大

4
我们公司正在尝试在一些基于Linux的嵌入式设备上使用Qt 4.8.5。我使用没有X服务器的Qt嵌入式。我需要绘制测量数据并经常更新它们(20-30fps,但只是小部分窗口小部件)。该系统基于ARM,400Mhz,没有GPU和FPU。我子类化了QWidget并重写了paintEvent()。我设置了WA_OpaquePaintEvent和WA_StaticContents。为了测试,我的paint event为空,并且我从定时器调用widget的update()函数,定时器设置为50毫秒。我的问题是,空的update占用了30%的CPU。数量随更新区域的大小而变化,因此我认为QT可能会在后台重新绘制某些内容。我已经阅读了很多帖子,但无法找到解决我的问题的方法。如果我注释掉update call,则CPU使用率下降到约1%(即使我在定时器中生成正弦波以测试窗口小部件,这应该比空函数调用复杂得多)。我的窗口小部件是矩形的,不透明的,并且我希望从paint event处理整个绘图过程。是否可以减少这种开销,并自己处理整个绘图过程?

如果您只想更新一个小部分,您是否尝试通过update(QRect)或update(QRegion)来限制更新区域? - Frank Osterfeld
是的,我尝试过。如果这样做,CPU使用率会随着区域大小的减小而下降。但例如,更新一个25像素宽的区域比两个相距15个未更改像素的5像素区域更便宜,后者不需要更新。为了调试,我完全禁用了我的绘图器,paintEvent只是一个空函数。我的问题是,如果我在paintEvent函数中什么都不做,为什么它还会使用CPU?(我知道它必须被调度和调用,但它应该是最小的开销,并且不应与更新区域成正比)。 - xdever
好的,如果您没有显式地绘制任何内容,小部件也将被更新,因为任何先前的内容都将被清除。 - Frank Osterfeld
这个能不能关掉?如果我绘制内容,它也会被清除,所以这只是浪费昂贵的 CPU 循环。即使我绘制小部件(与我之前评论中的 2x5 vs 1x25 像素更新相比),它也会加载 CPU。 - xdever
另一个问题是,如果清除会消耗 CPU 周期,那么为什么清除两个单独的 5x600 像素列比清除单个 25x600 要慢? - xdever
显示剩余4条评论
1个回答

1
"空更新"并不是真的空 - 它会重新绘制整个窗口 :)
你看过下面的内容吗?
为了快速更新具有简单背景颜色的自定义小部件(例如实时绘图或图形小部件),最好定义适当的背景颜色(使用QPalette :: Window角色设置setBackgroundRole()),设置autoFillBackground属性,并仅在小部件的paintEvent()中实现必要的绘制功能。
您还应该使用QWidget :: scroll(),因为在内部它会滚动窗口的后备存储,这比如果只添加了一个小片段而重新绘制整个窗口要高效得多。"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接