Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 为什么小部件第一次在QGridlayout中显示时会闪烁不定?_Qt_Pyside2_Qlayout - Fatal编程技术网

Qt 为什么小部件第一次在QGridlayout中显示时会闪烁不定?

Qt 为什么小部件第一次在QGridlayout中显示时会闪烁不定?,qt,pyside2,qlayout,Qt,Pyside2,Qlayout,我有一个QGridLayout,里面有很多小部件,我需要经常使用它们。我是这样做的,按照新排序的顺序一个接一个地替换它们 然而,这意味着,每添加一个小部件,布局都要更新自身并重新绘制其子部件,这会导致许多不必要的减速 我想告诉布局只是不要做任何布局或绘图,直到我完成添加我想添加的所有内容 我试图通过覆盖update()方法来实现这一点,在添加完所有小部件后,只调用父方法 def update(self): self._fill_layout() supe

我有一个
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
我试图通过在layouts
update
方法中使用
self.parentWidget().repaint()
手动触发重画来修复此问题,但这不会改变任何内容。小部件仍然没有显示


有没有更简单的方法告诉布局只计算自身,而不更新其视觉效果,然后手动触发绘制事件?

我找到了解决特定问题的方法,正如预期的那样,它很复杂

在我的小部件中,我有一个Gridlayout,我基本上用它来绘制一个条目表,它可以在组中设置为可见或不可见(展开一个子表)

当添加新数据时,只有一行是可见的,其余的行及其小部件被添加为“隐藏”的,这使得布局在更新自身时忽略它们

这意味着,每当我第一次要展开一行时,它的所有子行和它的小部件都将可见,布局将为每个小部件重新更新它的状态。在我的例子中,这可能在一行中发生几十次

为了避免这种情况,我在layout类的
setGeometry()
调用中添加了一个QTimer,以捕获连续的几十个调用,并等待几毫秒,然后在每次调用时重置计时器。只有在没有新调用传入时,我才会让
setGeometry()调用
调用get-through并允许布局自我更新

这使得布局方式更具响应性,但现在闪烁的小部件开始出现。当我展开一行时,我突然看到作为新行一部分的小部件在主小部件的左上角出现了过大的瞬间

起初,我认为这意味着,它们在
QTimer
仍处于活动状态时显示。它们显示为其父级的子级,但尚未成为布局的一部分。事实并非如此,但是,它们始终是布局的一部分,但由于我添加了它们,当它们不可见时,它们没有调整大小或更改大小正确定位并且使用
QTimer
我延迟了该操作,但没有延迟它们的绘制事件。这意味着它们在布局定位之前被绘制,然后在计时器用完时再次绘制

一旦我注意到了这一点,我就可以安装一个事件监听器来监听绘画事件,并在位置(0,0)处禁用所有小部件。这是一种解决问题的粗略方法,但我愿意这样做

然而,这并没有完全解决问题。我仍然可以看到一个大的空白方块出现,在小部件之前的位置。这很明显,因为一行中的小部件的背景/窗口颜色与正常的灰色不同

我认为这意味着,行中的一个空“单元格”仍然是以某种方式绘制的,我没有在事件侦听器中捕捉到它。然而,经过更多的研究,我发现,窗口或小部件的背景不是在绘制事件中绘制的,而是在与任何特定事件分离之前,我可以捕捉到的

这意味着我在一开始看到的小部件仍然存在,只是没有被绘制,所以只有它的背景被显示

因为我找不到阻止小部件背景绘制的方法,所以我选择只删除小部件的背景色,因为它只是稍微浅一点的灰色


我知道这显然是一个迹象,表明我没有使用正确的方法,但沉没的成本谬论+没有时间让我暂时坚持这一点。

您可能想利用
QWidget
@G.m.哪个小部件的属性?布局所在的小部件?是的。根据文档,应该相应地启用/禁用子小部件@G.M.没有改变我所看到的任何行为,很遗憾。请提供