dynamic method question

Jesse Aldridge JesseAldridge at gmail.com
Fri Jun 13 07:00:26 CEST 2008


So in the code below, I'm binding some events to a text control in
wxPython.  The way I've been doing it is demonstrated with the
Lame_Event_Widget class.  I want to factor out the repeating
patterns.  Cool_Event_Widget is my attempt at this.  It pretty much
works, but I have a feeling there's a better way of doing this.  Also,
I couldn't get the Cool_Text_Control to override the on_text method.
How would I do that?

-------------

import textwrap, new

import wx


class Lame_Event_Widget:
    def bind_events(self):
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.Bind(wx.EVT_RIGHT_DOWN, self.on_right_down)
        self.Bind(wx.EVT_MIDDLE_DOWN, self.on_middle_down)
        self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
        self.Bind(wx.EVT_RIGHT_UP, self.on_right_up)
        self.Bind(wx.EVT_TEXT, self.on_text)

    def on_left_down(self, e):
        print "lame normal method: on_left_down"
        e.Skip()

    def on_right_down(self, e):
        print "lame normal method: on_right_down"
        e.Skip()

    def on_middle_down(self, e):
        print "lame normal method: on_middle_down"
        e.Skip()

    def on_left_up(self, e):
        print "lame normal method: on_left_up"
        e.Skip()

    def on_right_up(self, e):
        print "lame normal method: on_right_up"
        e.Skip()

    def on_text(self, e):
        print "lame normal method: on_text"
        e.Skip()


class Cool_Event_Widget:
    def bind_events(self):
        method_names = textwrap.dedent(
            """
            on_left_down, on_right_down, on_middle_down,
            on_left_up, on_right_up, on_middle_up,
            on_text"""
            ).replace("\n", "").split(", ")

        for name in method_names:
            event_name = name.partition("_")[2]
            event_name = "wx.EVT_" + event_name.upper()

            exec("def " + name + "(self, e):\n" +
                 "    print 'cool dynamic method: " + name + "'\n" +
                 "    e.Skip()\n"
                 "self." + name + " = new.instancemethod(" + name + ",
self, self.__class__)\n"
                 "self.Bind(" + event_name + ", self." + name + ")")


if __name__ == "__main__":
    app = wx.App()
    frame = wx.Frame(None)
    panel = wx.Panel(frame)
    sizer = wx.BoxSizer(wx.VERTICAL)
    panel.SetSizer(sizer)

    class Cool_Text_Control(wx.TextCtrl, Cool_Event_Widget):
        def __init__(self, parent):
            wx.TextCtrl.__init__(self, parent)
            self.bind_events()

        def on_text(self, e):
            print "modified text in Cool_Text_Control"

    class Lame_Text_Control(wx.TextCtrl, Lame_Event_Widget):
        def __init__(self, parent):
            wx.TextCtrl.__init__(self, parent)
            self.bind_events()

        def on_text(self, e):
            print "modified text in Lame_Text_Control"

    sizer.Add(Cool_Text_Control(panel))
    sizer.Add(Lame_Text_Control(panel))

    frame.Show()
    app.MainLoop()



More information about the Python-list mailing list