I'm having an opaque moment. +5 brownie points to anyone who can enlighten.

The plan is to write a unit-testing module for the wxCanvas widget (good progress there :) )

So I wanted a row of different objects (similar to MS Paint) on buttons; the behavior of the different buttons would be to change which drawing function the canvas would be bound to upon click.

for each b in buttons:
   b.Bind(wx.EVT_LEFT_UP, change_callback(functions[b]))

change_callback(func):
   return function that binds canvas wx.EVT_LEFT_UP to func
self.buttons = {wx.Button(parent=self,label="rect"):self.draw_rectangle,
                        wx.Button(parent=self,label="poly"):self.draw_poly,
                        wx.Button(parent=self,label="circ"):self.draw_circle,
                        wx.Button(parent=self,label="line"):self.draw_line}
        for b in self.buttons:
            self.buttonsizer.Add(b)
            b.Bind(wx.EVT_LEFT_UP, self.change_callback(self.buttons[b]))

        ...

    def change_callback(self, func):
        #print func.__name__
        def cb(event):
            self.canvas.Bind(wx.EVT_LEFT_UP, func)
        return cb
        
    def draw_rectangle(self, event):
        x0,y0 = event.GetPosition()
        self.canvas.create_rectangle(x0,y0,x0+20,y0+20)
        self.canvas.Refresh()

    ...

Getting output from wx is frustrating enough. But I have been able to determine that (a) the correct functions are being passed to change_callback(), and (b) change_callback does indeed return a function.

So why doesn't it work?!?!

(Brownie points redeemable at the rate of 10,000 / brownie. Void where prohibited by law. Batteries included except where inclusion would violate international treaties.)

Jeff

OK, it turns out that it *does* work, sort of.

If I click on one of the buttons, the app locks up. Then if I click any other window, it unlocks and the app does the right thing. Then when I press a button again, it locks up. Repeat ad nauseum.

Is there a hidden rule about clearing the event queue after Bind-ing or something?

Jeff

Got it!

For buttons, the appropriate event is wx.EVT_BUTTON, as follows:

self.buttons = {wx.Button(parent=self,label="rect"):self.draw_rectangle,
                        wx.Button(parent=self,label="poly"):self.draw_poly,
                        wx.Button(parent=self,label="circ"):self.draw_circle,
                        wx.Button(parent=self,label="line"):self.draw_line}
        for b in self.buttons:
            self.buttonsizer.Add(b)
            b.Bind(wx.EVT_BUTTON, self.change_callback(self.buttons[b]))

        ...

    def change_callback(self, func):
        #print func.__name__
        def cb(event):
            self.canvas.Bind(wx.EVT_LEFT_UP, func)
        return cb
        
    def draw_rectangle(self, event):
        x0,y0 = event.GetPosition()
        self.canvas.create_rectangle(x0,y0,x0+20,y0+20)
        self.canvas.Refresh()

    ...

I'll eat the brownies myself. :P

Jeff

This question has already been answered. Start a new discussion instead.