编辑选项卡时关闭PyQt事件循环

2024-05-02 05:15:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用PyQt开发一个GUI。GUI有一个qListWidget、一个qTableWidget和一个用Mayavi实现的plot。该列表引用绘制的形状(例如圆柱体和圆锥体)。当在列表中选择一个形状时,我希望将该形状的属性加载到表中(从字典变量中),并在绘图中突出显示该形状。我让玛雅维人的阴谋运作良好。此外,如果编辑了表格,我需要重新打印形状,以反映新的特性值(如圆柱体,如果半径更改)。

因此,当选择列表项时->;使用项的属性(从字典变量中)更新表,在绘图中突出显示该项

编辑表时->;更新字典变量并重新打印项

问题是:当我选择一个列表项并将数据加载到表中时,qTableWidget ItemChanged信号在每次更新单元格时都会触发,这会多次触发用不完整数据重新绘制形状。

在以编程方式更新表时,是否存在禁用GUI事件循环的典型方法?(我有使用Excel VBA的经验,在该上下文设置应用程序中。EnableEvents=False将阻止每次以编程方式更新单元格时触发工作表更改事件。) 我是否应该有一个“table update in progress”变量来防止在更新表时执行操作? 有没有办法一次更新表小部件而不是逐项更新?(我承认我目前有意避免使用模型视图框架,因此使用qListWIdget和qTableWidget)。

有什么建议吗?

我是第一次发帖,但长期使用StackOverflow,所以我只是想提前感谢你成为了一个如此棒的社区!


Tags: 数据gt编辑绘图列表字典属性编程
3条回答

blockSignals(bool)旨在抑制QObjects及其子类发出信号,从而防止任何其他对象在插槽中接收它们。但这是一个QObject方法。如果您特别试图阻止一个对象响应您所做的更改而发出信号,这可能会触发计算或插槽中的其他一些昂贵的处理,那么这就是您想要的。

但是,如果您的情况是,重复更改会导致多次昂贵的绘制操作(或在小部件上生成其他昂贵的事件),那么您可以使用^{}禁用更新。这个方法的一个好处是它递归地禁用目标小部件的子部件,防止它们也被更新。因此,在重新启用之前,层次结构中的任何内容都不会接收更新。

mainWidget.setUpdatesEnabled(False)
# do a bunch of operations that would trigger expensive events
# like repaints
mainWidget.setUpdatesEnabled(True)

最终,这取决于问题的根源是来自触发信号,还是触发小部件事件。屏蔽这些信号仍将允许小部件处理其事件,但不通知任何其他侦听器。updatesEnabled是包装许多列表/表/树更新的常用方法。之后再次启用时,将执行单个更新后操作。

对于任何继承QObject的对象,信号可以临时blocked

self.tableWidget.blockSignals(True)
# perform updates, etc
self.tableWidget.blockSignals(False)

如果禁用整个事件循环,应用程序将变得无响应。而且,即使用户没有注意到,操作系统可能会,并提出某种“挂起”通知(就像OS X的色彩鲜艳的旋转沙滩球,没有用户会错过)。

您可能希望在不完全禁用事件循环的情况下禁用重绘。但即使这样也可能太激烈了。

您真正要做的是确保表停止重新绘制自己(不改变实现表视图的方式,您承认这并不理想,但您有理由这样做)。

所以,只需禁用ItemChanged更新。在几乎所有情况下,最简单的方法是调用小部件上的blockSignals(True)

在极少数情况下,这是行不通的(或者当你处理的是在基于Qt4的项目和早期项目中都要用到的古代代码时),你仍然可以获取信号的处理程序,将它们藏起来,删除它们,然后做你的工作,然后恢复之前的处理程序。

相反,您可以创建一个处理程序可以访问的标志,并对其进行更改,以便在设置了该标志时它们不执行任何操作。这是传统的C做事方式,但在Python中通常不是你想做的。

相关问题 更多 >