关闭PyQt的事件循环编辑时表(Turn off PyQt Event Loop While Edi

2019-08-03 17:36发布

我正在开发与PyQt的一个GUI。 该GUI具有qListWidget,一个QTableWidget的,并与Mayavi的实施的阴谋。 该列表是指绘制(例如圆柱和圆锥)的形状。 当在列表中选择的形状,我想要的形状的属性来被加载到表(从字典变量)和形状,以在图中被突出显示。 我有Mayavi的绘制工作正常。 此外,如果表被编辑时,我需要被重新绘制的形状,以反映新的属性值(如对于一个气缸,如果半径改变)。

所以,在选择列表项 - >更新与该项目的属性表(从字典变量),突出对剧情的项目

当表被编辑 - >更新字典变量和重新情节的项目

问题:当我选择列表项和数据装载到该表中,QTableWidget的ItemChanged信号火灾每一个小区被更新时,它与不完整的数据触发重新绘制的形状多次。

是否有禁用GUI事件循环,而表格被编程更新的典型手段? (我有经验与Excel VBA,在这方面设置Application.EnableEvents = false将阻止每一个细胞编程更新时间触发WorksheetChange事件)。我应该有可变一项“进展表更新”,以防止正在采取的行动,而对表进行更新? 有没有一种方法来更新表构件一次全部,而不是逐项? (我承认我是故意避开模型 - 视图框架的时刻,因此qListWIdget和QTableWidget的)。

有什么建议?

我是第一次海报,但StackOverflow上的很长一段时间的用户,所以我只想说,在此先感谢是这样一个真棒社区!

Answer 1:

blockSignals(bool)旨在用于抑制QObjects及其子类从发射信号,从而防止任何其他对象从在时隙接收它们。 但是,这是一个QObject方法。 如果你特别想阻止一个对象从响应到您正在变化,这可能会引发计算或其他一些昂贵的处理槽发射信号,那么这就是你想要的。

但如果你的情况是,做重复的变化是遍地造成昂贵的喷漆操作(或在小部件上产生其他昂贵的事件),那么你有禁用更新的能力updatesEnabled(bool) 。 这种方法的好处是,它递归禁用目标控件的孩子,防止它们被更新。 所以,直到你再次启用没有在层次结构将得到更新。

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

最终,它取决于你的问题的来源是否来自触发信号,或触发小部件事件。 阻断信号将仍然允许小部件处理它的事件,却唯独没有关于它的任何通知其他听众。 updatesEnabled是包装一个号码列表/表/树更新的常用方法。 当再次启用之后,单篇文章的更新将被执行。



Answer 2:

信号可以被暂时阻止该继承的任何对象QObject

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


Answer 3:

如果禁用了整个事件循环,应用程序变得没有反应。 而且,即使用户没有注意到,操作系统可能,并提出了某种“挂起”的通知(如OS X的色泽鲜艳的纺纱的皮球,这是任何用户都不会错过)。

你可能希望在不完全禁用事件循环禁用重绘 。 但是,即使这可能过于激烈。

所有你真的想要做的就是确保表停止重绘本身(不改变你实现你的表视图,你承认不理想的方式,但你有原因)。

所以,仅仅禁用ItemChanged更新。 要做到这一点,最简单的方式,在几乎所有情况下,是调用blockSignals(True)的小工具。

在极少数情况下,这是不行的(或者当你处理与古老的代码的意思在Qt4的基础和早期的项目中都被使用),你仍然可以得到的信号处理器(一个或多个),其中藏匿走,并删除它们,然后做你的工作,然后恢复到以前的处理程序(一个或多个)。

您可以改为创建一个处理程序可以访问一个标志,并改变它们,所以如果设置了标志,他们什么都不做。 这是做事的传统的C方式,但它通常不是你想要在Python做什么。



文章来源: Turn off PyQt Event Loop While Editing Table