trying to thread with toaster popups

I have an app that I am trying to use the Toaster class from here:
http://xoomer.alice.it/infinity77/eng/freeware.html

The trouble is that when the popups fire off the main gui locks up waiting for them to finish. Seems like a case to try to place the popups in their own thread and keep the main gui responsive. I'm trying that, but it's not working. I get errors such as:
Xlib: unexpected async reply (sequence 0x297)!

I've created a cut down example and have attached the toaster class as well.

This is my first wxPython project as well as my first time ever looking at threading so I wonder if I'm just missing something here.

Any help is appreciated.

Rick

thread_test.py (2.09 KB)

ToasterBox.py (21.8 KB)

Rick,

The error I get is somewhat more detailed running Python 2.5 and Wxpython 2.8

PyAssertionError: C++ assertion "wxThread::IsMain()" failed at ..\..\src\common\timercmn.cpp(66) in wxTimerBase::Start(): timer can only be started from the main thread

It appears that the ToasterBox is using a Timer internally (which makes sense, because it closes itself after a certain amount of time).

I know this doesn't fix your problem yet, but hopefully provides a little more insight.

Andrew

···

-----Original Message-----
From: Richard Harding [mailto:rharding@mitechie.com]
Sent: Wednesday, February 07, 2007 9:52 AM
To: wxPython-users@lists.wxwidgets.org
Subject: [wxPython-users] trying to thread with toaster popups

I have an app that I am trying to use the Toaster class from here:
http://xoomer.alice.it/infinity77/eng/freeware.html

The trouble is that when the popups fire off the main gui locks up
waiting for them to finish. Seems like a case to try to place the popups
in their own thread and keep the main gui responsive. I'm trying that,
but it's not working. I get errors such as:
Xlib: unexpected async reply (sequence 0x297)!

I've created a cut down example and have attached the toaster class as
well.

This is my first wxPython project as well as my first time ever looking
at threading so I wonder if I'm just missing something here.

Any help is appreciated.

Rick

I ran the app on Mac OSX/Python 2.5/wxPython 2.8.1 and got this exception:

CGContextRestoreGState: invalid context
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/threading.py",
line 460, in __bootstrap
    self.run()
  File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/threading.py",
line 440, in run
    self.__target(*self.__args, **self.__kwargs)
  File "thread_test.py", line 38, in RunMonitor
    self.RunToaster('Some string')
  File "thread_test.py", line 64, in RunToaster
    tb.Play()
  File "/Users/frank/Desktop/wxpythonuserstryingtothreadwithtoasterpopups/ToasterBox.py",
line 284, in Play
    if not self._tb.Play():
  File "/Users/frank/Desktop/wxpythonuserstryingtothreadwithtoasterpopups/ToasterBox.py",
line 556, in Play
    self.showtime.Start(self._pausetime)
  File "//Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/wx-2.8-mac-unicode/wx/_misc.py",
line 1298, in Start
    return _misc_.Timer_Start(*args, **kwargs)
PyAssertionError: C++ assertion "wxThread::IsMain()" failed at
/BUILD/wxPython-src-2.8.1.1/src/common/timercmn.cpp(66) in Start():
timer can only be started from the main thread

I did see the toasterbox slide upwards in the lower right corner, btw.

HTH, Frank

···

2007/2/7, Richard Harding <rharding@mitechie.com>:

I have an app that I am trying to use the Toaster class from here:
http://xoomer.alice.it/infinity77/eng/freeware.html

The trouble is that when the popups fire off the main gui locks up
waiting for them to finish. Seems like a case to try to place the popups
in their own thread and keep the main gui responsive. I'm trying that,
but it's not working. I get errors such as:
Xlib: unexpected async reply (sequence 0x297)!

I've created a cut down example and have attached the toaster class as
well.

This is my first wxPython project as well as my first time ever looking
at threading so I wonder if I'm just missing something here.

Any help is appreciated.

Pangborn, Andrew (ext. 324) wrote:

Rick,

The error I get is somewhat more detailed running Python 2.5 and Wxpython 2.8

PyAssertionError: C++ assertion "wxThread::IsMain()" failed at ..\..\src\common\timercmn.cpp(66) in wxTimerBase::Start(): timer can only be started from the main thread

It appears that the ToasterBox is using a Timer internally (which makes sense, because it closes itself after a certain amount of time).

I know this doesn't fix your problem yet, but hopefully provides a little more insight.

Thanks, I'm on python 2.5 and wx 2.6. The new error you sent gets me something else to look for now. I wonder why you can't use a timer outside the main thread. Oh well, looks like this is going to be a bit more complicated than juts "fire it off in a diff thread"

Rick

Richard Harding wrote:

Pangborn, Andrew (ext. 324) wrote:

Rick,

The error I get is somewhat more detailed running Python 2.5 and Wxpython 2.8

PyAssertionError: C++ assertion "wxThread::IsMain()" failed at ..\..\src\common\timercmn.cpp(66) in wxTimerBase::Start(): timer can only be started from the main thread

It appears that the ToasterBox is using a Timer internally (which makes sense, because it closes itself after a certain amount of time).

I know this doesn't fix your problem yet, but hopefully provides a little more insight.

Thanks, I'm on python 2.5 and wx 2.6. The new error you sent gets me something else to look for now. I wonder why you can't use a timer outside the main thread. Oh well, looks like this is going to be a bit more complicated than juts "fire it off in a diff thread"

Just for the record, looking at the Timer docs, it's an extension of threads so that makes sense that you can't start a thread from a thread kinda thing.

http://docs.python.org/lib/timer-objects.html

Rick

I think this might be a bit of a bug in the ToasterBox's "Play" function.
It seems to create a timer regardless of the closing style that is defined

Seems like the 5 lines regarding the Timer in Play() should be wrapped up like this

if self._closingstyle == TB_ONTIME:
     timerid = wx.NewId()
     self.showtime = wx.Timer(self, timerid)
     self.showtime.Start(self._pausetime)
     self.Bind(wx.EVT_TIMER, self.NotifyTimer, id=timerid)

However the "TB_ONCLICK" closing style doesn't appear to be working properly for me either.

Andrew

···

-----Original Message-----
From: Richard Harding [mailto:rharding@mitechie.com]
Sent: Wednesday, February 07, 2007 10:11 AM
To: wxPython-users@lists.wxwidgets.org
Subject: Re: [wxPython-users] trying to thread with toaster popups

Pangborn, Andrew (ext. 324) wrote:

Rick,

The error I get is somewhat more detailed running Python 2.5 and Wxpython 2.8

PyAssertionError: C++ assertion "wxThread::IsMain()" failed at ..\..\src\common\timercmn.cpp(66) in wxTimerBase::Start(): timer can only be started from the main thread

It appears that the ToasterBox is using a Timer internally (which makes sense, because it closes itself after a certain amount of time).

I know this doesn't fix your problem yet, but hopefully provides a little more insight.

Thanks, I'm on python 2.5 and wx 2.6. The new error you sent gets me
something else to look for now. I wonder why you can't use a timer
outside the main thread. Oh well, looks like this is going to be a bit
more complicated than juts "fire it off in a diff thread"

Rick

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

It has more to do with the way in which the events are handled. Spawning a thread from a thread in not an intrinsic problem (the "main" thread is just a thread afterall).

···

-----Original Message-----
From: Richard Harding [mailto:rharding@mitechie.com]
Sent: Wednesday, February 07, 2007 10:15 AM
To: wxPython-users@lists.wxwidgets.org
Subject: Re: [wxPython-users] trying to thread with toaster popups

Just for the record, looking at the Timer docs, it's an extension of
threads so that makes sense that you can't start a thread from a thread
kinda thing.

http://docs.python.org/lib/timer-objects.html

Rick

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Pangborn, Andrew (ext. 324) wrote:

I think this might be a bit of a bug in the ToasterBox's "Play" function.
It seems to create a timer regardless of the closing style that is defined

Seems like the 5 lines regarding the Timer in Play() should be wrapped up like this

if self._closingstyle == TB_ONTIME:
     timerid = wx.NewId()
     self.showtime = wx.Timer(self, timerid)
     self.showtime.Start(self._pausetime)
     self.Bind(wx.EVT_TIMER, self.NotifyTimer, id=timerid)

However the "TB_ONCLICK" closing style doesn't appear to be working properly for me either.

Yea, there are a few bugs I've corrected with the corner placement in there as well. I haven't tried the OnClick close method yet. The main issue I have is that the popups lock up the main gui and I'm not sure why it should, especially after seeing that it running on a timer should be a sort of threading.

The lockup can get pretty bad in my app. It displays updates from remote subversion repositories using pysvn and if you have more than one repository the lag is pretty bad.

Looks like it's time to start reading up on python profiling to see what can be done.

Rick

Hi All,

> I think this might be a bit of a bug in the ToasterBox's
"Play" function.
> It seems to create a timer regardless of the closing style that is
> defined

Yes, it is a bug indeed.

>
> Seems like the 5 lines regarding the Timer in Play() should
be wrapped
> up like this
>
> if self._closingstyle == TB_ONTIME:
> timerid = wx.NewId()
> self.showtime = wx.Timer(self, timerid)
> self.showtime.Start(self._pausetime)
> self.Bind(wx.EVT_TIMER, self.NotifyTimer, id=timerid)
>

This should be the correct implementation. However, it does crash in any case with the previous error message. I implemented ToasterBox quite a long ago (I believe I was using wxPython 2.5), and I never tried to run it from a different thread. For me it's just a small whistle & bell addition to wxPython, and I use it only to notify for software upgrades or similar. I recognize that for more intense messaging, it's not well suited.

> However the "TB_ONCLICK" closing style doesn't appear to be
working properly for me either.

Uhm, it works for me. There are problems in using this style when coupled with the TB_COMPLEX style, because you can add as many widgets as you want to the ToasterBox, and if you click on any of those widget, the click event is not propagated to the parent frame (usual problem with wxWidgets). The only possibility here is to make ToasterBox bind all the widgets' wx.EVT_LEFT_DOWN event and to propagate this event to the parent frame.

Yea, there are a few bugs I've corrected with the corner
placement in there as well.

Would you mind contributing it back, as a patch or something similar? In this way I could update my web page with the new version.

The main issue I have is that the popups lock up
the main gui and I'm not sure why it should, especially after
seeing that it running on a timer should be a sort of threading.

The lockup can get pretty bad in my app. It displays updates
from remote subversion repositories using pysvn and if you
have more than one repository the lag is pretty bad.

During implementation, I used wxTimer because it was the easiest and cleanest solution for my purposes. However, if you come up with a nicer implementation, I would be glad to have a patch and to integrate it in a new version.

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Gavana, Andrea wrote:

However the "TB_ONCLICK" closing style doesn't appear to be

working properly for me either.

Uhm, it works for me. There are problems in using this style when coupled with the TB_COMPLEX style, because you can add as many widgets as you want to the ToasterBox, and if you click on any of those widget, the click event is not propagated to the parent frame (usual problem with wxWidgets). The only possibility here is to make ToasterBox bind all the widgets' wx.EVT_LEFT_DOWN event and to propagate this event to the parent frame.

Ah, that makes sense. Thanks for the info.

Yea, there are a few bugs I've corrected with the corner placement in there as well.

Would you mind contributing it back, as a patch or something similar? In this way I could update my web page with the new version.

Email away, I sent a previous message when i first messed with them to a wrong email address it looks like.

The main issue I have is that the popups lock up the main gui and I'm not sure why it should, especially after seeing that it running on a timer should be a sort of threading.

The lockup can get pretty bad in my app. It displays updates from remote subversion repositories using pysvn and if you have more than one repository the lag is pretty bad.

During implementation, I used wxTimer because it was the easiest and cleanest solution for my purposes. However, if you come up with a nicer implementation, I would be glad to have a patch and to integrate it in a new version.

It works well for the most part. You can see a screenshot of what I'm trying to do here:
http://mitechie.com/uploads/avant_svn_toasters.png

It's the same kind of notification thing. In the end I hope to turn it into something that runs in the system tray so the unresponsive main gui isn't really a huge deal at that point. I just wanted to see if there was something I could do with it or not.

Thanks

Rick

Richard Harding wrote:

I have an app that I am trying to use the Toaster class from here:
http://xoomer.alice.it/infinity77/eng/freeware.html

The trouble is that when the popups fire off the main gui locks up waiting for them to finish. Seems like a case to try to place the popups in their own thread and keep the main gui responsive. I'm trying that, but it's not working. I get errors such as:
Xlib: unexpected async reply (sequence 0x297)!

You can't do GUI stuff from anything but the main thread. X-Windows for example is notorious for not being thread-safe, and some of the other platforms make you jump through hoops to do it too, so wx just doesn't support it.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Richard Harding wrote:

I have an app that I am trying to use the Toaster class from here:
http://xoomer.alice.it/infinity77/eng/freeware.html

The trouble is that when the popups fire off the main gui locks up waiting for them to finish. Seems like a case to try to place the popups in their own thread and keep the main gui responsive. I'm trying that, but it's not working. I get errors such as:
Xlib: unexpected async reply (sequence 0x297)!

You can't do GUI stuff from anything but the main thread. X-Windows for example is notorious for not being thread-safe, and some of the other platforms make you jump through hoops to do it too, so wx just doesn't support it.

Thanks, that makes sense. What I did do to test it out was to move the popup code to it's own app and when the two are seperated it works fine. My question becomes, how can I launch/close a seperate application from within wxpython? This way I can still have the controls for starting/stopping the popups in one app and the popups are run from a second seperate one that does not bind up the original giu?

Thanks for any help.

Rick

Richard Harding wrote:

Robin Dunn wrote:

Richard Harding wrote:

I have an app that I am trying to use the Toaster class from here:
http://xoomer.alice.it/infinity77/eng/freeware.html

The trouble is that when the popups fire off the main gui locks up waiting for them to finish. Seems like a case to try to place the popups in their own thread and keep the main gui responsive. I'm trying that, but it's not working. I get errors such as:
Xlib: unexpected async reply (sequence 0x297)!

You can't do GUI stuff from anything but the main thread. X-Windows for example is notorious for not being thread-safe, and some of the other platforms make you jump through hoops to do it too, so wx just doesn't support it.

Thanks, that makes sense. What I did do to test it out was to move the popup code to it's own app and when the two are seperated it works fine. My question becomes, how can I launch/close a seperate application from within wxpython? This way I can still have the controls for starting/stopping the popups in one app and the popups are run from a second seperate one that does not bind up the original giu?

Thanks for any help.

Ok, never mind on this. I've decided that since the end goal was to make this a system tray type app to go ahead and move that way. In this way it will run in the background and out of the way.

My question is at this point is how can I have a window come up, on top of all other windows, and not get the focus so that it doesn't take the pointer away from the current application a user is interacting with?

Thanks

Rick

Rick

Richard Harding wrote:

My question is at this point is how can I have a window come up, on top of all other windows, and not get the focus so that it doesn't take the pointer away from the current application a user is interacting with?

Experiment with some of the other frame styles. Some of them are intended to make the frame be a tool window for a main frame, and won't mess with the main frame's activation/focus etc. I don't know if they will act the same if there isn't a main frame though, and there are probably some platform differences too...

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!