我正在用PyQt开发一个GUI。GUI有一个qListWidget、一个qTableWidget和一个用Mayavi实现的plot。该列表引用绘制的形状(例如圆柱体和圆锥体)。当在列表中选择一个形状时,我希望将该形状的属性加载到表中(从字典变量中),并在绘图中突出显示该形状。我让玛雅维人的阴谋运作良好。此外,如果编辑了表格,我需要重新打印形状,以反映新的特性值(如圆柱体,如果半径更改)。
因此,当选择列表项时->;使用项的属性(从字典变量中)更新表,在绘图中突出显示该项
编辑表时->;更新字典变量并重新打印项
问题是:当我选择一个列表项并将数据加载到表中时,qTableWidget ItemChanged信号在每次更新单元格时都会触发,这会多次触发用不完整数据重新绘制形状。
在以编程方式更新表时,是否存在禁用GUI事件循环的典型方法?(我有使用Excel VBA的经验,在该上下文设置应用程序中。EnableEvents=False将阻止每次以编程方式更新单元格时触发工作表更改事件。) 我是否应该有一个“table update in progress”变量来防止在更新表时执行操作? 有没有办法一次更新表小部件而不是逐项更新?(我承认我目前有意避免使用模型视图框架,因此使用qListWIdget和qTableWidget)。
有什么建议吗?
我是第一次发帖,但长期使用StackOverflow,所以我只是想提前感谢你成为了一个如此棒的社区!
blockSignals(bool)
旨在抑制QObjects
及其子类发出信号,从而防止任何其他对象在插槽中接收它们。但这是一个QObject
方法。如果您特别试图阻止一个对象响应您所做的更改而发出信号,这可能会触发计算或插槽中的其他一些昂贵的处理,那么这就是您想要的。但是,如果您的情况是,重复更改会导致多次昂贵的绘制操作(或在小部件上生成其他昂贵的事件),那么您可以使用^{} 禁用更新。这个方法的一个好处是它递归地禁用目标小部件的子部件,防止它们也被更新。因此,在重新启用之前,层次结构中的任何内容都不会接收更新。
最终,这取决于问题的根源是来自触发信号,还是触发小部件事件。屏蔽这些信号仍将允许小部件处理其事件,但不通知任何其他侦听器。
updatesEnabled
是包装许多列表/表/树更新的常用方法。之后再次启用时,将执行单个更新后操作。对于任何继承
QObject
的对象,信号可以临时blocked:如果禁用整个事件循环,应用程序将变得无响应。而且,即使用户没有注意到,操作系统可能会,并提出某种“挂起”通知(就像OS X的色彩鲜艳的旋转沙滩球,没有用户会错过)。
您可能希望在不完全禁用事件循环的情况下禁用重绘。但即使这样也可能太激烈了。
您真正要做的是确保表停止重新绘制自己(不改变实现表视图的方式,您承认这并不理想,但您有理由这样做)。
所以,只需禁用ItemChanged更新。在几乎所有情况下,最简单的方法是调用小部件上的
blockSignals(True)
。在极少数情况下,这是行不通的(或者当你处理的是在基于Qt4的项目和早期项目中都要用到的古代代码时),你仍然可以获取信号的处理程序,将它们藏起来,删除它们,然后做你的工作,然后恢复之前的处理程序。
相反,您可以创建一个处理程序可以访问的标志,并对其进行更改,以便在设置了该标志时它们不执行任何操作。这是传统的C做事方式,但在Python中通常不是你想做的。
相关问题 更多 >
编程相关推荐