From: Wanderer on
I have a wxPython program which does some calculations and displays
the results. During these calculations if I click the mouse inside the
dialog the program locks up. If I leave the dialog alone the process
completes fine. I have tried running the function from a separate
dialog with Show Modal and I have tried using SetEvtHandlerEnabled all
to no avail. The program is long and occupies several files so I won't
show the whole thing but here is the calculation part. How do I block
events?

def DoEfficiency(self):

from time import sleep

self.timer.Stop()



TotalPower = 0
Counter = 0
for ang in range(1,89):
self.tc_angle.SetValue(ang)
height = int(self.eclwidth * 10)
for hgt in range(0,height):
self.tc_height.SetValue(float(hgt)/10.0)
self.UpdateValues()
self.Redraw()
self.DrawRays()
sPower = self.tc_power.GetValue()
Power = sPower.split('%')
TotalPower +=float(Power[0])
Counter +=1
sleep(0.1)

efficiency = TotalPower/Counter
self.tc_eff.SetLabel(str(round(efficiency,1)))
self.timer.Start(10)


# end DoEfficiency

def OnEfficiency(self, event):

self.tc_aangle.SetEvtHandlerEnabled(False)
self.tc_angle.SetEvtHandlerEnabled(False)
self.tc_calc_len.SetEvtHandlerEnabled(False)
self.tc_cpclength.SetEvtHandlerEnabled(False)
self.tc_cpcwidth.SetEvtHandlerEnabled(False)
self.tc_det.SetEvtHandlerEnabled(False)
self.tc_ecl.SetEvtHandlerEnabled(False)
self.tc_eff.SetEvtHandlerEnabled(False)
self.tc_gap1.SetEvtHandlerEnabled(False)
self.tc_gap2.SetEvtHandlerEnabled(False)
self.tc_height.SetEvtHandlerEnabled(False)
self.tc_parab.SetEvtHandlerEnabled(False)
self.tc_power.SetEvtHandlerEnabled(False)
self.tc_refresh.SetEvtHandlerEnabled(False)
self.tc_tlength.SetEvtHandlerEnabled(False)
self.tc_twidth.SetEvtHandlerEnabled(False)
self.tc_use_tir.SetEvtHandlerEnabled(False)
self.SetEvtHandlerEnabled(False)

dlf = CalcEfficiency(self,"CalcEfficiency",wx.DefaultPosition,
(90,60))

self.tc_aangle.SetEvtHandlerEnabled(True)
self.tc_angle.SetEvtHandlerEnabled(True)
self.tc_calc_len.SetEvtHandlerEnabled(True)
self.tc_cpclength.SetEvtHandlerEnabled(True)
self.tc_cpcwidth.SetEvtHandlerEnabled(True)
self.tc_det.SetEvtHandlerEnabled(True)
self.tc_ecl.SetEvtHandlerEnabled(True)
self.tc_eff.SetEvtHandlerEnabled(True)
self.tc_gap1.SetEvtHandlerEnabled(True)
self.tc_gap2.SetEvtHandlerEnabled(True)
self.tc_height.SetEvtHandlerEnabled(True)
self.tc_parab.SetEvtHandlerEnabled(True)
self.tc_power.SetEvtHandlerEnabled(True)
self.tc_refresh.SetEvtHandlerEnabled(True)
self.tc_tlength.SetEvtHandlerEnabled(True)
self.tc_twidth.SetEvtHandlerEnabled(True)
self.tc_use_tir.SetEvtHandlerEnabled(True)
self.SetEvtHandlerEnabled(True)

# end MyInterface


class CalcEfficiency(wx.Dialog):
"""
"""
def __init__(self, parent, title, pos, size):

self.parent = parent


wx.Dialog.__init__(self,parent, -1, title, pos, size)

self.runButton = wx.ToggleButton(self, ID_TOGGLE, "Start",
wx.DefaultPosition, (70,30))
self.Bind(wx.EVT_TOGGLEBUTTON, self.OnToggle, id =
ID_TOGGLE)

self.ShowModal()

self.Destroy()

# end init

def OnToggle(self, event):

if self.runButton.GetValue():
self.runButton.SetLabel("WAIT")
self.SetEvtHandlerEnabled(False)
self.parent.DoEfficiency()
self.SetEvtHandlerEnabled(True)
else:
self.Close()


# end OnQuit

# end CalcEfficiency


if __name__ == '__main__':
app = MyApp(False)
app.MainLoop()

# end main
From: zeph on
The wxPython wiki actually has a page on dealing with long running
tasks called from event handlers called (surprise surprise):
http://wiki.wxpython.org/LongRunningTasks

Hint: the second to last example on that page has the clearest example
- using a worker thread object to do your DoEfficiency() function.

I also don't think you want to disable so many event handlers, do
you? Nothing will respond to inputs as long as that process is
running (assuming you aren't running it in another thread.)
From: Philip Semanchuk on

On Dec 9, 2009, at 10:42 AM, Wanderer wrote:

> I have a wxPython program which does some calculations and displays
> the results. During these calculations if I click the mouse inside the
> dialog the program locks up. If I leave the dialog alone the process
> completes fine. I have tried running the function from a separate
> dialog with Show Modal and I have tried using SetEvtHandlerEnabled all
> to no avail. The program is long and occupies several files so I won't
> show the whole thing but here is the calculation part. How do I block
> events?


Hi Wanderer,
I don't have a solution for you but I have three suggestions.

First, your program shouldn't be locking up just because you clicked
on it. IMO that's the real problem, and discarding events is just a
band-aid to cover it up. Nevertheless, sometimes a band-aid is an
appropriate solution and you're the best judge of that.

Second, the wxPython mailing list would be a better place for this
question.

Third, if you can't seem to resolve the problem, try paring it down to
a minimal example that reproduces the problem. It's difficult to offer
suggestions when we can't see the whole code or try the sample code
ourselves.


Good luck
Philip
From: r0g on
Wanderer wrote:
> I have a wxPython program which does some calculations and displays
> the results. During these calculations if I click the mouse inside the
> dialog the program locks up. If I leave the dialog alone the process
> completes fine.

If anything in your GUI app takes a non trivial length of time to
execute you need to run it in either a thread or a separate process.

http://linuxgazette.net/107/pai.html

Roger
From: Wanderer on
On Dec 9, 11:48 am, r0g <aioe....(a)technicalbloke.com> wrote:
> Wanderer wrote:
> > I have a wxPython program which does some calculations and displays
> > the results. During these calculations if I click the mouse inside the
> > dialog the program locks up. If I leave the dialog alone the process
> > completes fine.
>
> If anything in your GUI app takes a non trivial length of time to
> execute you need to run it in either a thread or a separate process.
>
> http://linuxgazette.net/107/pai.html
>
> Roger

Thanks Everyone. I'll have to look over these wikis about threading. I
decided to go another route and user a timer to perform the loops.
That way the events can be processed normally.

def DoEfficiency(self, event):


ang = self.tc_angle.GetValue()
hgt = self.tc_height.GetValue()
hgt += 0.1
if hgt > self.eclwidth:
hgt = 0
ang +=1
self.tc_angle.SetValue(ang)
self.height = hgt
self.tc_height.SetValue(hgt)
self.tc_height.SetValue(hgt)
self.UpdateValues()
self.Redraw()
self.DrawRays()
sPower = self.tc_power.GetValue()
Power = sPower.split('%')
self.TotalPower +=float(Power[0])
self.Counter +=1
efficiency = self.TotalPower/self.Counter
self.tc_eff.SetLabel(str(round(efficiency,1)))
if ang > 89:
self.efftimer.Stop()
self.timer.Start(10)



# end DoEfficiency

def OnEfficiency(self, event):

self.TotalPower = 0
self.Counter = 0
self.tc_angle.SetValue(1)
self.tc_height.SetValue(0)
self.timer.Stop()
self.efftimer.Start(100)


# end MyInterface

Found another strange bug (Strange to me, anyway). int(0.8 * 10.0) =
7. Had to change the code to int(0.8 * 10.0 + 0.0001).