Error: "attempt to install idle handler twice.."

I'm baffled on this one. I added threading, and it hates me.

I've got a little wxList, I select one, and then hit my toggle button to
start a cycle. It waits two seconds, selects the next one,
waits...selects. It was using wxYield() and sleep() to make it wait
(and give control back to the gui). Now, I've added threading, and
taking out yeild.

Now, whenever it tries to change the state or focus of the selected
item, I get this

<big snip>

In RefreshCurrentOrigImage currentOrigImage is:
/home/mdg/pics/Feb03_05_Birthday1_004.jpg
In SetCurrentImageType, image is:
/home/mdg/pics/Feb03_05_Birthday1_004.jpg
You clicked a jpg
[Debug] 05:32:53 PM: C++ assertion "wxTheApp->m_idleTag == 0" failed in
/usr/src/redhat/BUILD/wxPythonSrc-2.4.0.2/src/gtk/app.cpp(364): attempt
to install idle handler twice
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/lib/python2.2/threading.py", line 408, in __bootstrap
    self.run()
  File "/usr/local/lib/python2.2/threading.py", line 396, in run
    apply(self.__target, self.__args, self.__kwargs)
  File "GpmToolBar.py", line 278, in StartSlideShow
    self.OnArrowRight(event)
  File "GpmToolBar.py", line 240, in OnArrowRight
    self.baseParent.gpmGuiFile.fileList.SetItemState(newIndex,
wxLIST_STATE_FOCUSED, wxLIST_STATE_FOCUSED)
  File "/usr/local/lib/python2.2/site-packages/wxPython/controls2.py",
line 477, in SetItemState
    val = apply(controls2c.wxListCtrl_SetItemState,(self,) + _args,
_kwargs)
wxPyAssertionError: C++ assertion "wxTheApp->m_idleTag == 0" failed in
/usr/src/redhat/BUILD/wxPythonSrc-2.4.0.2/src/gtk/app.cpp(364): attempt
to install idle handler twice

[Debug] 05:32:54 PM: C++ assertion "wxTheApp->m_idleTag == 0" failed in
/usr/src/redhat/BUILD/wxPythonSrc-2.4.0.2/src/gtk/app.cpp(364): attempt
to install idle handler twice
Traceback (most recent call last):
  File "GpmToolBar.py", line 146, in OnToolOver
    currentTool = event.GetSelection()
  File "/usr/local/lib/python2.2/site-packages/wxPython/events.py", line
126, in GetSelection
    val = apply(eventsc.wxCommandEvent_GetSelection,(self,) + _args,
_kwargs)
wxPython.wxc.wxPyAssertionError: C++ assertion "wxTheApp->m_idleTag ==
0" failed in
/usr/src/redhat/BUILD/wxPythonSrc-2.4.0.2/src/gtk/app.cpp(364): attempt
to install idle handler twice

</big snip>

Any ideas? Or any hits on that general error?

Matt

You can't run GUI code in more than one thread. Are you?

From the F.A.Q. at http://wiki.wxpython.org/

3.2 How do I use multiple threads?

All calls to methods of GUI objects and event handlers need to
happen on the main thread. In wxPython the main thread is the
one that first imports the wxPython.wx module. Other threads
can send events to the main thread using wxPostEvent as is done
in the Threads sample in the wxPython demo.

For more information and examples, please see LongRunningTasks.

(That's http://wiki.wxpython.org/index.cgi/LongRunningTasks )

···

At 17:37 2003-03-17 -0700, Matt Graham wrote:

I'm baffled on this one. I added threading, and it hates me.

--
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/ mailto:magnus@thinkware.se

Matt Graham wrote:

I'm baffled on this one. I added threading, and it hates me.

I've got a little wxList, I select one, and then hit my toggle button to
start a cycle. It waits two seconds, selects the next one,
waits...selects.

If you want something to happen every N seconds, this just screams to me that you should be using wxTimer. (Unless the task you're performing may take approx. N seconds or more to complete.)

As someone else already noted, calling GUI code from two threads is a big no-no, though you can use wxPostEvent and such (or Queue.Queue) to send messages from a secondary thread to your GUI thread. However, if you just want a simple short task to happen every two seconds, you can have your toggle button start (or kill) a wxTimer, and then simply perform your task in the EVT_TIMER handler, with no need for multithreading.

Jeff Shannon
Technician/Programmer
Credit International

You're exactly right...I'm caling gui stuff in my thread. That totally
makes sense.

I'll give the wxTimer a shot. I just need the gui to have control back
while the 2 or 3 second process is happening. I think a wxTimer should give
me that, vs the sleep() I'm using now.

Though...the threading stuff is really cool. I am sure I can find uses for
it elsewhere...big computations etc.

Thanks again for your time,
Matt

···

----- Original Message -----
From: "Jeff Shannon" <jeff@ccvcorp.com>
To: <wxPython-users@lists.wxwindows.org>
Sent: Tuesday, March 18, 2003 11:19 AM
Subject: Re: [wxPython-users] Error: "attempt to install idle handler
twice.."

Matt Graham wrote:

>I'm baffled on this one. I added threading, and it hates me.
>
>I've got a little wxList, I select one, and then hit my toggle button to
>start a cycle. It waits two seconds, selects the next one,
>waits...selects.
>

If you want something to happen every N seconds, this just screams to me
that you should be using wxTimer. (Unless the task you're performing
may take approx. N seconds or more to complete.)

As someone else already noted, calling GUI code from two threads is a
big no-no, though you can use wxPostEvent and such (or Queue.Queue) to
send messages from a secondary thread to your GUI thread. However, if
you just want a simple short task to happen every two seconds, you can
have your toggle button start (or kill) a wxTimer, and then simply
perform your task in the EVT_TIMER handler, with no need for

multithreading.

Jeff Shannon
Technician/Programmer
Credit International

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

The LongRunningTasks wiki page doesn't mention using Queues. When people
use this technique what is the set up? For example, is your "worker
thread" pushing data into the queue and then a wx.Timer is polling it
out with a non-blocking q.get_nowait()?

···

On Tuesday 18 March 2003 10:19 am, Jeff Shannon wrote:

Matt Graham wrote:
>I'm baffled on this one. I added threading, and it hates me.
>
>I've got a little wxList, I select one, and then hit my toggle
> button to start a cycle. It waits two seconds, selects the next
> one, waits...selects.

If you want something to happen every N seconds, this just screams to
me that you should be using wxTimer. (Unless the task you're
performing may take approx. N seconds or more to complete.)

As someone else already noted, calling GUI code from two threads is a
big no-no, though you can use wxPostEvent and such (or Queue.Queue)
to send messages from a secondary thread to your GUI thread.
However, if you just want a simple short task to happen every two
seconds, you can have your toggle button start (or kill) a wxTimer,
and then simply perform your task in the EVT_TIMER handler, with no
need for multithreading.

--
Chuck
http://ChuckEsterbrook.com

Chuck Esterbrook wrote:

The LongRunningTasks wiki page doesn't mention using Queues. When people use this technique what is the set up? For example, is your "worker thread" pushing data into the queue and then a wx.Timer is polling it out with a non-blocking q.get_nowait()?

That's one way. Another is to call wxWakeUpIdle when the item is put in the Queue, and then have a EVT_IDLE handler that fetches items from the queue. That way the item is usually processed very soon after it is put there without having to have a higher frequency timer. Another option is to not use the queue or wxPostEvent and just use wxCallAfter passing to it the callable and parameters to be called in the GUI thread. (It uses wxPostEvent internally.) The implementation and docs of wxCallAfter is in wx.py.

···

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

Chuck Esterbrook wrote:

The LongRunningTasks wiki page doesn't mention using Queues. When people use this technique what is the set up? For example, is your "worker thread" pushing data into the queue and then a wx.Timer is polling it out with a non-blocking q.get_nowait()?

I would recommend having the queue checked in an idle handler, and then having your worker thread call wxWakeUpIdle() when it puts something in the queue.

Jeff Shannon
Technician/Programmer
Credit International