我正在开发与PyQt的一个GUI。 该GUI具有qListWidget,一个QTableWidget的,并与Mayavi的实施的阴谋。 该列表是指绘制(例如圆柱和圆锥)的形状。 当在列表中选择的形状,我想要的形状的属性来被加载到表(从字典变量)和形状,以在图中被突出显示。 我有Mayavi的绘制工作正常。 此外,如果表被编辑时,我需要被重新绘制的形状,以反映新的属性值(如对于一个气缸,如果半径改变)。
所以,在选择列表项 - >更新与该项目的属性表(从字典变量),突出对剧情的项目
当表被编辑 - >更新字典变量和重新情节的项目
问题:当我选择列表项和数据装载到该表中,QTableWidget的ItemChanged信号火灾每一个小区被更新时,它与不完整的数据触发重新绘制的形状多次。
是否有禁用GUI事件循环,而表格被编程更新的典型手段? (我有经验与Excel VBA,在这方面设置Application.EnableEvents = false将阻止每一个细胞编程更新时间触发WorksheetChange事件)。我应该有可变一项“进展表更新”,以防止正在采取的行动,而对表进行更新? 有没有一种方法来更新表构件一次全部,而不是逐项? (我承认我是故意避开模型 - 视图框架的时刻,因此qListWIdget和QTableWidget的)。
有什么建议?
我是第一次海报,但StackOverflow上的很长一段时间的用户,所以我只想说,在此先感谢是这样一个真棒社区!
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
是包装一个号码列表/表/树更新的常用方法。 当再次启用之后,单篇文章的更新将被执行。
信号可以被暂时阻止该继承的任何对象QObject
:
self.tableWidget.blockSignals(True)
# perform updates, etc
self.tableWidget.blockSignals(False)
如果禁用了整个事件循环,应用程序变得没有反应。 而且,即使用户没有注意到,操作系统可能,并提出了某种“挂起”的通知(如OS X的色泽鲜艳的纺纱的皮球,这是任何用户都不会错过)。
你可能希望在不完全禁用事件循环禁用重绘 。 但是,即使这可能过于激烈。
所有你真的想要做的就是确保表停止重绘本身(不改变你实现你的表视图,你承认不理想的方式,但你有原因)。
所以,仅仅禁用ItemChanged更新。 要做到这一点,最简单的方式,在几乎所有情况下,是调用blockSignals(True)
的小工具。
在极少数情况下,这是不行的(或者当你处理与古老的代码的意思在Qt4的基础和早期的项目中都被使用),你仍然可以得到的信号处理器(一个或多个),其中藏匿走,并删除它们,然后做你的工作,然后恢复到以前的处理程序(一个或多个)。
您可以改为创建一个处理程序可以访问一个标志,并改变它们,所以如果设置了标志,他们什么都不做。 这是做事的传统的C方式,但它通常不是你想要在Python做什么。