编辑表时关闭 PyQt 事件循环 [英] Turn off PyQt Event Loop While Editing Table

查看:72
本文介绍了编辑表时关闭 PyQt 事件循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 PyQt 开发 GUI.GUI 有一个 qListWidget、一个 qTableWidget 和一个用 Mayavi 实现的绘图.该列表指的是绘制的形状(例如圆柱体和圆锥体).当在列表中选择一个形状时,我希望将形状的属性加载到表中(从字典变量中)并在图中突出显示该形状.我的 Mayavi 绘图工作正常.此外,如果表格被编辑,我需要重新绘制形状,以反映新的属性值(如圆柱体,如果半径发生变化).

所以,选择列表项时 - >使用项目的属性更新表(从字典变量),突出显示绘图上的项目

编辑表格时 -> 更新字典变量并重新绘制项目

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

在以编程方式更新表时,是否有禁用 GUI 事件循环的典型方法?(我有使用 Excel VBA 的经验,在该上下文中设置 Application.EnableEvents=False 将防止每次以编程方式更新单元格时触发 WorksheetChange 事件.)我应该有一个正在进行的表更新"变量来防止在更新表时采取行动吗?有没有办法一次更新表格小部件而不是逐项更新?(我承认我现在有意避免使用 Model-View 框架,因此使用了 qListWIdget 和 qTableWidget).

有什么建议吗?

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

解决方案

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

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

mainWidget.setUpdatesEnabled(False)# 做一堆会触发昂贵事件的操作# 喜欢重绘mainWidget.setUpdatesEnabled(True)

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

I'm developing a GUI with PyQt. The GUI has a qListWidget, a qTableWidget, and a plot implemented with Mayavi. The list refers to shapes that are plotted (cylinders and cones for example). When a shape is selected in the list, I want the shape's properties to be loaded into the table (from a dictionary variable) and the shape to be highlighted in the plot. I've got the Mayavi plotting working fine. Also, if the table is edited, I need the shape to be re-plotted, to reflect the new property value (like for a cylinder, if the radius is changed).

So, when a list item is selected -> update the table with the item's properties (from a dictionary variable), highlight the item on the plot

When the table is edited -> update the dictionary variable and re-plot the item

The Problem: when I select a list item and load data into the table, the qTableWidget ItemChanged signal fires every time a cell is updated, which triggers re-plotting the shape numerous times with incomplete data.

Is there a typical means of disabling the GUI event loop while the table is being programmatically updated? (I have experience with Excel VBA, in that context setting Application.EnableEvents=False will prevent triggering a WorksheetChange event every time a cell is programmatically updated.) Should I have a "table update in progress" variable to prevent action from being taken while the table is being updated? Is there a way to update the Table Widget all at once instead of item by item? (I'll admit I'm intentionally avoiding Model-View framework for the moment, hence the qListWIdget and qTableWidget).

Any suggestions?

I'm a first time poster, but a long time user of StackOverflow, so I just want to say thanks in advance for being such an awesome community!

解决方案

blockSignals(bool) is intended for suppressing QObjects and their subclasses from emitting signals, thus preventing any other objects from receiving them in slots. But this is a QObject method. If you are specifically trying to prevent one object from emitting signals in response to changes that you are making, which might trigger calculations or some other expensive processing in a slot, then this is what you want.

But if your situation is that making repeated changes is causing expensive paint operations over and over (or other expensive events being generated on the widget), then you have the ability to disable updates with updatesEnabled(bool). A benefit of this method is that it recursively disables the children of the target widget, preventing them from being updated as well. So nothing in the hierarchy will receive updates until you enable again.

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

Ultimately it depends on whether the source of your problem comes from triggering signals, or triggering widget events. Blocking the signals will still allow the widget to process its events, but just not notify any other listeners about it. updatesEnabled is a common way to wrap a number of list/table/tree updates. When it is enabled again afterwards, a single post update will be performed.

这篇关于编辑表时关闭 PyQt 事件循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆