简介:我正在编写一个应用程序,它在带有 VBoxlayout(“ScopeView”)的容器小部件中显示自定义 QWidgets(即“ScopeWidget”)列表。
每个 scopeWidget 都有一个指向自己的数据源类(“Scope”)的指针。这些对象在逻辑上按组排列,即一组对象之间存在一些共享参数(“ScopeShared”)。在检索(或准备)必须在 scopeWidget 上显示的数据时需要这些参数。
更进一步:scopeWidget 需要两组参数:这些由“Scope”给定,由“ScopeGroup”给定。scopeWidget 可以通过用户操作更改组中的某些共享参数,从而使该组中“Scope”持有的所有先前检索到的数据无效。默认情况下,“范围”中没有可显示的数据。数据是按需检索的——当一个paintEvent发生时(这是问题的根源)。要在“范围”中获得可显示的数据,必须处理该特定组中的所有“范围”(这会为该组中的所有“范围”生成可用数据)。
工作原理:用户强制其中一个 scopeWidgets 更改组中的共享数据。进行这些更改后,该组中“Scope”持有的所有数据都将失效,因此更改事件会重新处理整个组。并为此组中的所有 scopeWidgets 调用 update()。小部件被重绘。这行得通……</p>
问题:……是一个自发发生的paintEvent。当用户更改某些内容时——我知道这发生了,我可以在将小部件更新入队之前处理 scopeGroup。但是当“其他东西”(系统本身)执行绘画事件时,我需要在任何绘画发生之前处理整个组。所以paint事件不直接进行绘制,而是执行scopeGroup处理,然后,它绘制具有绘制事件的小部件,并为该组中的所有其他小部件调用update()——这反过来又会引发新的绘制事件,这导致下一个 scopeGroup 处理,一个paint() 和 update() 用于其他小部件,这会导致新的绘制事件——它最终作为递归重绘(和 scopeGroup 处理)
蹩脚的解决方案:标志——自发的绘画事件进行组处理,一个paint()用于请求的小部件,更新()在组中的其余小部件上,以及为每个小部件设置标志。
这个伪代码描述了这种机制:
paintEvent(QWidget *w)
{
if(w->flag)
{
w->paint(); w->flag=0;
}
else
{
w->group()->process();
w->paint();
QWidget *x;
foreach(x,group) if(x!=w) { x->flag=1; x->update(); }
}
恕我直言,什么会更好:
a)如果可以在没有事先绘制事件(或调用 update() 或 repaint() )的情况下绘制小部件……这将是最好的;],但它不能以直接和明显的方式工作——还有其他方法吗?- 或者
b) 强制系统调用自定义函数而不是绘制事件
这些“更好”的解决方案可能吗?