wxPython 从 4.0.7 迁移到 4.1.0:事件处理时出现 ListCtrl 错误

wxPython migration from 4.0.7 to 4.1.0: ListCtrl error while event handling

我目前正在从 wxPython 4.0.7 迁移到 wxPython 4.1.0。这将 wx 版本从 3.0.x 更改为 3.1.x.

Tl;博士: 使用 wx.ListCtrl 当我在 wxEVT_SIZE 事件处理程序中调用 event.Skip() 时有时会出错。 Skip() 还是不Skip()? (即 wxEVT_SIZE 的默认事件处理是什么,我需要它吗?)


长版:

wxEVT_SIZE 处理程序中使用 wx.ListCtrlevent.Skip 在我的 某些 表单中产生错误(所以我认为必须更多)。现在,我无法剥离任何事件以得到一个最小的示例,因为当我删除(看似)不相关的代码部分时,错误会随机消失。当我用较短的标签替换长标签时,错误甚至会消失(有时)。但是,更改框架或面板大小不会改变任何内容。

这是我发现的:

似乎我可以简单地删除 wxEVT_SIZE 处理程序中的 event.Skip() 调用并完成,但相关的 C++ 代码似乎还有更多内容。

这是错误(注意:错误不会使 wxApp 崩溃):

wx._core.wxAssertionError: C++ assertion "nNew != dynamicEvents.size()" failed at ..\..\src\common\event.cpp(1926) in wxEvtHandler::SearchDynamicEventTable():

The above exception was the direct cause of the following exception:

SystemError: <class 'wx._core.SizeEvent'> returned a result with an error set

github 存储库中的相关 C++ 代码可在此处找到:https://github.com/wxWidgets/wxWidgets/blob/e803408058186a7a9a61c456246f145abcaccd13/src/common/event.cpp#L1926

(提示:这是 wxPython 4.1.0 版本中使用的固定 wxWidget 版本)

这里有 wx 和 C++ 专家,他们可能知道发生了什么事吗?

我相信只有当处理程序从其事件处理程序调用 Bind() 时才会触发此断言,但会跳过该事件,即假装该事件根本未被处理。在一个理想的世界中,这应该是可能的,我认为断言实际上过于急切,需要放松,但现在,如果你真的需要这样做,你必须:

  1. 使用CallAfter()推迟呼叫Bind()
  2. 或避免调用 event.Skip().

(请注意,在这种情况下不会始终触发断言,您还需要删除之前不久之前连接到同一对象的处理程序)。

但一般来说你应该调用 Skip() 除非你已经完全处理了事件并且不想要任何其他处理程序,无论是基础 class 中的处理程序还是内置的处理程序运行 在你之后。对于 wxEVT_SIZE,这意味着您已经自己执行了 window 的重新布局,并且不希望基础 class 做任何事情。所以解决方案 (1) 更好,因为即使您确实希望基础 class 处理程序到 运行.

也可以使用它