GeezerVison is showing github.com — RuntimeError: wrapped C/C++ object of type _Event has been deleted · Issue #265 · wxWidgets/Phoenix
RuntimeError: wrapped C/C++ object of type _Event has been deleted #265
Description
"""
Minimal code to reproduce wx.PyEvent issue.
Output on my laptop:
sys.executable: /Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
sys.version: 2.7.10 (v2.7.10:15c95b7d81dc, May 23 2015, 09:33:12)
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]
wx.version(): 3.0.3.dev2891+36b8076 osx-cocoa (phoenix)
ThreadWorker 1: event._getAttrDict().keys() = ['nextEvent']
Exception in thread Thread-1:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "pyeventissue.py", line 45, in ThreadWorker
% event._getAttrDict().keys())
RuntimeError: wrapped C/C++ object of type _Event has been deleted
"""
import sys
import threading
import wx
import wx.lib.newevent as NE
MyEventClass, myEventBinder = NE.NewEvent()
def MyEventHandler(event):
"""
Event handler which starts a thread worker (taking event as an argument).
Uncommenting the event.Clone() stuff fixes the above RuntimeError for me.
"""
# if 'phoenix' in wx.PlatformInfo:
# event = event.Clone()
def ThreadWorker(event):
sys.stdout.write("ThreadWorker 1: event._getAttrDict().keys() = %s\n"
% event._getAttrDict().keys())
wx.CallAfter(wx.BeginBusyCursor)
sys.stdout.write("ThreadWorker 2: event._getAttrDict().keys() = %s\n"
% event._getAttrDict().keys())
threading.Thread(target=ThreadWorker, args=[event]).start()
class MyApp(wx.App):
def OnInit(self):
self.frame = wx.Frame(None, title="MyApp")
self.frame.Bind(myEventBinder, MyEventHandler)
self.frame.Show()
wx.CallAfter(self.AfterMainLoopHasStarted)
return True
def AfterMainLoopHasStarted(self):
nextEvent = wx.PyEvent()
wx.PostEvent(self.frame, MyEventClass(nextEvent=nextEvent))
sys.stdout.write("\nsys.executable: %s\n" % sys.executable)
sys.stdout.write("sys.version: %s\n" % sys.version)
sys.stdout.write("wx.version(): %s\n" % wx.version())
MyApp().MainLoop()
Activity
RobinD42 commented on Apr 6, 2017
Ok, I wasn't thinking things all the way through yesterday. It is working as expected and the event should be cloned before giving it to the worker thread.
Basically, Clone is called when wx.PostEvent is called, and the clone is put on the pending event queue. Later, after the event has been processed and its event handler returns, it is removed from the queue and that destroys the C++ object for the cloned event. In your example it appears that it is happening when the thread blocks momentarily for setting the busy cursor.
Metadata
Metadata
Development
No branches or pull requestsIssue actions