Hi there
I have some confusing problems with threading and wxpython (2.5.3 with
py2.4) When user clicks a button i fire another thread (which is subclass
of threading.Thread). I give my topwindows AddPendingEvent (discovered
wx.CallAfter later but it doesn't help so I stuck on AddPendingEvent) as a
reference to that thread. I also display a 'wait-a-second'-dialog where
user can cancel the thread if wanted so (In fact the operation cannot be
canceled but the events for results will not be shown). I also give that
dialog as a reference (because i do not want to store it in
self.something).
Then when thread finishes it's job (gets result or exception) I post new
xthreadresults event which has the result as event.object and the original
waitdialog as event.dd. The thread will not trigger that event if user has
pressed cancel so I can safely say event.dd.EndModal(wx.ID_OK) in
eventhandler. but then the strange part begins... assertion error,
EndModal can only be called on modal dialogs, IsModal returns False. Well
the IsModal truly returns False, altough the dialog is for sure modal.
I've compared the addresses of shown dialog and the reference and it's
still the same dialog. This does work on gtk (no errors, everything fine)
but on msw it thinks the dialog is not modal.
It doesnt help if I store the dialog in main-class as self.something and
leave the whole dialog-passing away from threading so I assume it has
nothing to do with broken references (like reference is taken before
ShowModal() and ShowModal() tweaks something nasty etc..) Also the only
wx-function the thread calls is Frames AddPendingEvent and I couldn't find
a better way to pass data into mainloop (and inform the mainloop that
something has happened) - I assume that using AddPendingEvent is not
breaking the rules not to do any gui-related things in threads (As I read
from ASPN that CallAfter can be used safely from threads)
Later when the thread has finished it's job it fires ThreadCloseEvent
that'll eventually be processed in function that .Destroy() the
wait-dialog and .join() the thread.
I have the code in pastebin as http://wiki.wxwidgets.org/paste.cgi?id=854
it has some old-style event stuff (because it will work on 2.4 or 2.5 or
so). I tried to strip down extra code to get the minumum failing code.
And again, it's not failing under gtk, but under msw. the output of the
program is as follows:
Z:\threadtest>main.py
dialog is: 20655856
on threadClose
now the dialog is: 20655856 False
Traceback (most recent call last):
File "Z:\threadtest\main.py", line 132, in _check
event.dd.EndModal(wx.ID_OK)
File
"C:\Python24\Lib\site-packages\wx-2.5.3-msw-unicode\wx\_windows.py",
line 615, in EndModal
return _windows_.Dialog_EndModal(*args, **kwargs)
wx._core.PyAssertionError: C++ assertion "IsModal()" failed in
..\..\src\msw\dialog.cpp(360): EndModal() called for non modal dialog
So if you have any ideas please share them with me. and yet wx.Yield +
idle-loop is not an options. thanks
Miika