As you've guessed, care needs to be taken when destroying UI objects from their own event handlers. Not only is the current event handler still active, but there may be other pending events that are still in the queue, and if the target object has been destroyed when they are delivered then you can get a crash.
The best thing to do is to defer the destruction until after the current and possible pending event handlers have been completed and there is nothing waiting to be done on the UI object except for the destruction that you want to do. And the best way to do that is to use wx.CallAfter
. It will call a function with parameters that you give it the next time the the event loop empties, so implicitly there is not anything else waiting to be done or sent to the UI object in question.
In your case it would be safe to do things like immediately remove the page from the notebook, and hide the page window. Then use wx.CallAfter
to call some function (perhaps in the notebook class) which calls the page window's Destroy
method and does any other cleanup that is necessary. The reason I suggest splitting these two sets of tasks is not because it will take a long time for the function to be called, but in some cases it may be long enough to flicker momentarily in a transitory state, so the appearance is less smooth for the users.