wxPython.button.disabled still catching clicks

Mike Driscoll kyosohma at gmail.com
Tue Dec 23 12:12:11 EST 2008


On Dec 23, 7:27 am, mynthon <mynth... at gmail.com> wrote:
> On Dec 23, 11:58 am, Aaron Brady <castiro... at gmail.com> wrote:
>
>
>
> > On Dec 23, 4:50 am, mynthon <mynth... at gmail.com> wrote:
>
> > > Hello! (sorry for my english)
>
> > > I have a problem with buttons in wxPython. When button is disabled
> > > (by .Disable() or .Enable(False)) it is grayed out but still receive
> > > clicks.
>
> > > Eg. i have button that disable itself, runs long action and enable
> > > itself:
>
> > > def onClick(self, evt):
> > >     self.btn.Enable(False)
> > >     for i in range (1000):
> > >         print i
> > >     self.btn.Enable(True)
>
> > > when for loop is running button is greyed out and when i click on it
> > > nothing happens but when loop ends another one is started because
> > > button "remebered" thad i click on it when was diabled. My only idea
> > > is to reposition button outside frame instead of disabling it but this
> > > solution is...not good.
>
> > > thanks for any help. Ive searched groups, google and it looks that
> > > only i have this problem :)
>
> > No, it is very common.  During your for loop, the loop is dominating
> > the process completely.  Events are just building up in the app's
> > message queue, and don't get handled until after you yield on control.
>
> > If you need to run a long task, look into threading, the OnIdle
> > method, the 'multiprocessing' module, or pump messages during your
> > long task.
>
> ok, maybe someone will need it. I dont know how it works because i
> didnt have time to read docs and i cannot explain everything. I used
> google and wxPython demo (in tree: wxpython overview / process and
> events / process)
>
> class leftPanel(wx.Panel):
>     def __init__(self, parent, id):
>         wx.Panel.__init__(self, parent, id, style=wx.BORDER_SUNKEN)
>
>         # here you have to define new process, IDLE event, and
> onPRocessEnd event
>         self.process = None
>         self.GetParent().Bind(wx.EVT_IDLE, self.onIdle)
>         self.Bind(wx.EVT_END_PROCESS, self.onProcessEnd)
>
>         # create button and bind event to it
>         self.runScriptBtn = wx.Button(self, -1, 'RUN ME!', (10,220))
>         self.runScriptBtn.Bind(wx.EVT_BUTTON, self.onClick,
> self.runScriptBtn)
>
>     def onClick(self, evt):
>         # disable button
>         self.runScriptBtn.Enable(False)
>
>         # here you have to enter command to run
>         # previusly i heve here exec('python myScript.py')
>         # but now it will be a subprocess
>         cmd = 'python xxx1.py'
>
>         #create new process
>         self.process = wx.Process(self)
>
>         # dont know what it is for
>         self.process.Redirect()
>
>         # execute cmd command
>         pid = wx.Execute(cmd, wx.EXEC_ASYNC, self.process)
>
>     def onIdle(self, evt):
>         # beacuse this method is called only when app enters idle mode
>         # the line below is nedded to "simulate" entering idle mode
>         # dont know how it works but it works
>         evt.RequestMore(True)
>
>         # here is some code to catch subprocess output
>         if self.process is not None:
>             stream = self.process.GetInputStream()
>             if stream.CanRead():
>                 text = stream.read()
>                 print text
>
>     def onProcessEnd(self, evt):
>         # here is some code to catch subprocess output
>         # when it is destroyed
>         stream = self.process.GetInputStream()
>         if stream.CanRead():
>             text = stream.read()
>             print text
>
>         # dont know it is necessary
>         self.process.CloseOutput()
>
>         # remove (clear) process object
>         self.process.Destroy()
>         self.process = None
>
>         # show button again
>         self.runScriptBtn.Enable()

I'm pretty sure there's a better way to do this. If you disable the
button and click on it, you'll notice that it isn't firing events, so
something else is going on here. It seems like the wx.Frame or
wx.Application is queuing the mouse button clicks or something. I
would post to the wxPython mailing list: http://wxpython.org/maillist.php

They'll be better able to address this and they'll probably have a
simpler solution too.

Mike



More information about the Python-list mailing list