wxPython.button.disabled still catching clicks

mynthon mynthon1 at gmail.com
Tue Dec 30 04:04:33 EST 2008


On Dec 23, 6:12 pm, Mike Driscoll <kyoso... at gmail.com> wrote:
> 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('pythonmyScript.py')
> >         # but now it will be a subprocess
> >         cmd = 'pythonxxx1.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

I changed it. Now i'm running separate thread instead of process.
First example at:
http://wiki.wxpython.org/LongRunningTasks



More information about the Python-list mailing list