Re: wxPython.button.disabled still catching clicks



On Dec 23, 11:58 am, Aaron Brady <castiro...@xxxxxxxxx> wrote:
On Dec 23, 4:50 am, mynthon <mynth...@xxxxxxxxx> 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()
.