wxPython 中加速器的编程绑定



我正在尝试以编程方式在循环中创建和绑定wxPython中的加速器表,这样我就不必担心为每个加速器获取和分配新ID(并且着眼于从某些外部资源中吸入处理程序列表,而不是硬编码它们)。我还通过 lambda 将一些参数传递给处理程序,因为我的许多处理程序都是相同的,但具有不同的参数(移动、缩放等)。

该类是从 wx 子类化的。帧和setup_accelerators()在初始化期间调用。

def setup_accelerators(self):
    bindings = [
                  (wx.ACCEL_CTRL,  wx.WXK_UP, self.on_move, 'up'),
                  (wx.ACCEL_CTRL,  wx.WXK_DOWN, self.on_move, 'down'),
                  (wx.ACCEL_CTRL,  wx.WXK_LEFT, self.on_move, 'left'),
                  (wx.ACCEL_CTRL,  wx.WXK_RIGHT, self.on_move, 'right'),
                  ]

    accelEntries = []
    for binding in bindings:
        eventId = wx.NewId()
        accelEntries.append( (binding[0], binding[1], eventId) )
        self.Bind(wx.EVT_MENU, lambda event: binding[2](event, binding[3]), id=eventId)

    accelTable = wx.AcceleratorTable(accelEntries)
    self.SetAcceleratorTable(accelTable)
def on_move(self, e, direction):
    print direction

但是,这似乎将所有加速器绑定到最后一个条目,以便 Ctrl+Up 打印"right",就像所有其他三个一样。如何以这种方式正确绑定多个处理程序?

知道了。 问题是你没有按照你的方向传递作为你的lambda的参数(它只是看事件参数(和自我),因为这就是你的lambda被定义为接受的全部)这个页面给了我让它工作所需的帮助(这是一个要点):

import wx
class MyForm(wx.Frame):
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Programmatic binding of accelerators in wxPython", size=(450,150))
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        bindings = [
                  (wx.ACCEL_CTRL,  wx.WXK_UP, 'up'),
                  (wx.ACCEL_CTRL,  wx.WXK_DOWN, 'down'),
                  (wx.ACCEL_CTRL,  wx.WXK_LEFT, 'left'),
                  (wx.ACCEL_CTRL,  wx.WXK_RIGHT, 'right'),
                  ]

        accelEntries = []
        for binding in bindings:
            eventId = wx.NewId()
            accelEntries.append( (binding[0], binding[1], eventId) )
            self.Bind(wx.EVT_MENU, lambda evt, temp=binding[2]: self.on_move(evt, temp), id=eventId)
        accelTable  = wx.AcceleratorTable(accelEntries)
        self.SetAcceleratorTable(accelTable )
     #----------------------------------------------------------------------
    def on_move(self, Event, direction):
        print "You pressed CTRL+"+direction
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()

我最初的答案(这是一个可接受的替代解决方案)是:

import wx
class MyForm(wx.Frame):
    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Tutorial", size=(500,500))
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        bindings = [
                  (wx.ACCEL_CTRL,  wx.WXK_UP, self.on_move_up),
                  (wx.ACCEL_CTRL,  wx.WXK_DOWN, self.on_move_down),
                  (wx.ACCEL_CTRL,  wx.WXK_LEFT, self.on_move_left),
                  (wx.ACCEL_CTRL,  wx.WXK_RIGHT, self.on_move_right),
                  ]

        accelEntries = []
        for binding in bindings:
            eventId = wx.NewId()
            accelEntries.append( (binding[0], binding[1], eventId) )
            self.Bind(wx.EVT_MENU, binding[2], id=eventId)
        accelTable  = wx.AcceleratorTable(accelEntries)
        self.SetAcceleratorTable(accelTable )
     #----------------------------------------------------------------------
    def on_move_up(self, event):
        print "You pressed CTRL+up"
    def on_move_down(self, event):
        print "You pressed CTRL+down"
    def on_move_left(self, event):
        print "You pressed CTRL+left"
    def on_move_right(self, event):
        print "You pressed CTRL+right"
# Run the program
if __name__ == "__main__":
    app = wx.App(False)
    frame = MyForm()
    frame.Show()
    app.MainLoop()

相关内容

  • 没有找到相关文章

最新更新