wxPython:菜单快捷键的作用域与动态禁用

0 投票
1 回答
1086 浏览
提问于 2025-04-17 05:51

我在 Arch Linux x86_64 上使用 Python 2.7.2 和 wxPython 2.8.12.1。

我想让下面这个例子这样工作:
* 当左边的文本框(text_A)有焦点时,按下 Shift+A 应该执行 do_A(),而按下 Shift+B 应该在文本区域写入 B;同时,menu.foo.bar_B 应该被禁用(而 menu.foo.bar_A 应该被启用)
* 当右边的文本框(text_B)有焦点时,按下 Shift+A 应该在文本区域写入 A,而按下 Shift+B 应该执行 do_B();同时,menu.foo.bar_A 应该被禁用(而 menu.foo.bar_B 应该被启用)

import wx


class Foo(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, size=(600, 480))

        self.init_menu()
        self.init_text()

        self.Centre()
        self.Show(True)

    def init_menu(self):
        self.menu = wx.MenuBar()
        self.SetMenuBar(self.menu)

        self.menu.foo = wx.Menu()
        self.menu.Append(self.menu.foo, "&Foo")

        self.menu.foo.bar_A = self.menu.foo.Append(wx.ID_ANY, "Bar&A\tShift+A")
        self.menu.foo.bar_B = self.menu.foo.Append(wx.ID_ANY, "Bar&B\tShift+B")

        self.Bind(wx.EVT_MENU, self.handle_A, self.menu.foo.bar_A)
        self.Bind(wx.EVT_MENU, self.handle_B, self.menu.foo.bar_B)

    def init_text(self):
        self.box = wx.BoxSizer(wx.HORIZONTAL)
        self.SetSizer(self.box)

        self.text_A = wx.TextCtrl(self, style=wx.TE_MULTILINE)
        self.text_B = wx.TextCtrl(self, style=wx.TE_MULTILINE)

        self.box.Add(self.text_A, 1, flag=wx.EXPAND)
        self.box.Add(self.text_B, 1, flag=wx.EXPAND)

    def handle_A(self, event):
        print('A')

    def handle_B(self, event):
        print('B')

app = wx.App()
Foo()
app.MainLoop()

用类似 self.text_A.Bind(wx.EVT_MENU, self.handle_A, self.menu.foo.bar_A) 的方式绑定菜单事件完全不管用。

我应该使用 wx.EVT_KILL_FOCUSwx.EVT_SET_FOCUS 来绑定/解绑菜单项,设置/重置快捷键,以及启用/禁用菜单项吗?这听起来对于较大的应用程序来说有点复杂,通常我想知道 wxPython 应用程序限制菜单快捷键作用范围并动态启用/禁用菜单项的正确(最常用、干净整洁)方法是什么。

谢谢!

1 个回答

1

我几年前写了一篇关于菜单的文章,地址在这里:http://www.blog.pythonlibrary.org/2008/07/02/wxpython-working-with-menus-toolbars-and-accelerators/

文章里讲了如何禁用菜单。wxPython的演示包里也有一个相关的例子。不过,我觉得你得把菜单事件绑定到框架对象上,直接绑定到文本控件上可能不太行。我认为在处理焦点事件时做启用或禁用的操作会更合适。

如果想要解除绑定某个事件,可以用UnBind方法。想了解更多信息,可以查看这两个链接:http://zetcode.com/wxpython/events/http://www.wxpython.org/docs/api/wx.EvtHandler-class.html

撰写回答