timer can only be started from the main thread

Hi,
I have a small issue with wxPython 2.9.4.0 on Windows 7 which ends with
PyAssertionError: C++ assertion “wxThread::IsMain()” failed at …\src\common\timerimpl.cpp(61) in wxTimerImpl::Start(): timer can only be started from the main thread

This is as a result of a wx.FutureCall()
I see that wx.FutureCall() can’t be run from a thread that isn’t the main, but the function that has the wx.FutureCall is not in a secondary thread, however does gets called as a result of a pubsub event from a secondary thread.
Is this a bug?.. If not how do I call a wx.FutureCall after Ive got data back from pubsub. I don’t see any issue with thread safeness as other GUI updates have already successfully completed as a result of the pubsub data. Error attached

Cheers,
Lawrie

error.txt (1.84 KB)

Lawrence Abbott wrote:

Hi,
I have a small issue with wxPython 2.9.4.0 on Windows 7 which ends with
PyAssertionError: C++ assertion "wxThread::IsMain()" failed at
..\..\src\common\timerimpl.cpp(61) in wxTimerImpl::Start(): timer can
only be started from the main thread

This is as a result of a wx.FutureCall()
I see that wx.FutureCall() can't be run from a thread that isn't the
main, but the function that has the wx.FutureCall is not in a secondary
thread, however does gets called as a result of a pubsub event from a
secondary thread.

Then it is being executed in the secondary thread. The location of the code does not determine which thread they are run in, but rather it is which thread the caller of the function is running in, and its caller, and its caller... If you look closer at your traceback you'll see that there is a direct line from pub.sendMessage which is running in Thread-1, down through the pubsub code, to the function that is calling wx.FutureCall.

Is this a bug?...

Yes. A bug in your code.

If not how do I call a wx.FutureCall after Ive got
data back from pubsub.

You need to hand over the data/command/whatever to something running in the GUI thread. An easy way to do that is to use wx.CallAfter since it works by posting an event to the pending event queue and that queue is only processed in the GUI thread. If you really need to wait some time seconds before doing anything then the code called via wx.CallAfter can create use wx.CallLater there to wait for the 2 seconds, otherwise you can just perform whatever actions you need there.

···

--
Robin Dunn
Software Craftsman

Hello Robin,
Thanks for the education…

wx.CallAfter(my_function_with_wx.CallLater_in) does the job (as you suggested).

Cheers,
Lawrie

···

On Sunday, 2 June 2013 12:57:47 UTC+8, Lawrence Abbott wrote:

Hi,
I have a small issue with wxPython 2.9.4.0 on Windows 7 which ends with
PyAssertionError: C++ assertion “wxThread::IsMain()” failed at …..\src\common\timerimpl.cpp(61) in wxTimerImpl::Start(): timer can only be started from the main thread

This is as a result of a wx.FutureCall()
I see that wx.FutureCall() can’t be run from a thread that isn’t the main, but the function that has the wx.FutureCall is not in a secondary thread, however does gets called as a result of a pubsub event from a secondary thread.
Is this a bug?.. If not how do I call a wx.FutureCall after Ive got data back from pubsub. I don’t see any issue with thread safeness as other GUI updates have already successfully completed as a result of the pubsub data. Error attached

Cheers,
Lawrie