【发布时间】:2020-01-03 11:51:52
【问题描述】:
我有一个带有很多小部件的QGridLayout,我需要经常使用它们。我这样做是按照新排序的顺序一一替换它们。
然而,这意味着,对于每个添加的小部件,布局都希望更新自身并重新绘制其子级,这会导致很多不必要的减速。
我想告诉布局不要做任何布局或绘图,直到我完成添加我想要添加的所有内容。
我正在尝试通过覆盖 update() 方法并仅在添加完所有小部件后调用父方法来做到这一点。
def update(self):
self._fill_layout()
super(MyLayout, self).update()
这似乎仍然没有消除所有的减速,所以我还捕获了对 setGeometry() 的所有调用,并且仅在最后一次调用它的 20 毫秒后调用它的父版本。
def setGeometry(self, screen_rect=None):
if screen_rect is not None:
self._last_requested_geometry = screen_rect
self._delayed_redraw_timer.start(20)
else:
# called by our timer
return super(MyLayout, self).setGeometry(self._last_requested_geometry)
然而,这会导致一些小部件被显示,虽然它们不是布局的一部分,而只是父小部件的一部分(我假设,因为它们位于左上角并且比它们应该的更大。所以它们似乎是画出来的,而我还在布置它们。
我为小部件安装了一个事件过滤器,具体取决于它们是否在布局中。但这似乎产生了相反的效果,因为小部件现在没有绘制(更准确地说,只有背景是)。我假设给我带来麻烦的绘制事件被阻止了,但之后没有其他事件发生,所以它们被放入布局但不再重绘?
def eventFilter(self, watched, event) -> bool:
if event.type() == QEvent.Paint:
return watched.layout() is None
return False
我尝试通过手动触发重绘来解决此问题,在 self.parentWidget().repaint() 布局中使用 update 方法,但这不会改变任何东西。小部件仍未显示。
有没有更简单的方法来告诉布局只计算自己,而不更新其视觉效果,然后手动触发该绘制事件?
【问题讨论】:
-
您可能想要使用
QWidget的updatesEnabled属性。 -
@G.M.哪个小部件?布局所在的那个?
-
是的。根据应该相应地启用/禁用子小部件的文档。
-
@G.M.不幸的是,不会改变我目睹的任何行为。