在 wxPython 中保留一系列 ID

Reserving a range of IDs in wxPython

我正在用 wxPython 为 I2C 设备编写一个更大的 GUI 应用程序。当程序启动时,它会从 XML 文件动态生成设备菜单。它首先为每个 'type' 设备(EEPROM、多路复用器、IOExpander 等)附加一个子菜单,然后在每个子菜单中附加实际设备的名称。因为直到 运行 时间才创建菜单,所以我必须即时分配 ID。此外,由于 XML 文件会不时更新新的 "types" 设备,我不仅需要知道选择了哪个项目,还需要知道该项目来自哪个子菜单。我目前实现这个的方法是在我分配项目的 ID 中有一个 "parent-child" 关系。目前,其中一个菜单项的 ID 是一个 3 位数字:第一个数字总是 2,所以我知道它来自设备菜单。第二位是选择的子菜单,最后一位是所选的具体设备。为了存储这些 ID,我将它们添加到字典中,其中 ID 是键,设备名称是值。

submenu_id = -1
    for device_type in self.device_list:
        submenu = wx.Menu()
        submenu_id += 1
        device_menu_id = -1
        for device in device_type.m_device_list:
            device_menu_id += 1
            device_id = 200 + (submenu_id * 10) + device_menu_id
            id_list[device_id] = device.m_name
            item = wx.MenuItem(submenu, device_id, device.m_name, wx.EmptyString, wx.ITEM_NORMAL)
            submenu.AppendItem(item)
        menu.AppendSubMenu(submenu, device_type.m_name)

现在,我有两个问题。最紧迫的问题是我需要保留 200 到 299 的 ID 范围,其中包含可以分配给设备项的所有可能 ID。如果我调用 wx.ID_ANY,它有时会为其他菜单分配该范围内的 ID,这意味着我的绑定都搞砸了。另一个问题是我觉得这样做有点做作。目前,我只能有 10 个不同类型的设备子菜单,每个子菜单中只有 10 个设备。在可预见的未来,这应该足够了,但是我希望能够在尽可能多的不同类别中添加尽可能多的设备。此外,执行此操作的代码非常丑陋和混乱,我真的很希望有人阅读我的代码知道我到底在做什么。

所以,我的第一个问题是:有没有办法保留我需要的 ID 范围,这样我就不会与 wx 发生任何冲突?

我的第二个问题,有没有更好的方法来做到这一点?

参见 wx.RegisterId(id)。简而言之,wx.NewId 非常简单。它只是增加一个内部计数器和 returns 没有额外智能的值。如果您使用 wx.RegisterId(id),那么该计数器将设置为给定的值,因此 wx.NewId 返回的下一个值将是 > id。因此,您可以将其设置为某个值,然后低于该值的所有内容(尚未为系统 ID 保留,例如 wx.ID_OK)都可以被您的代码用作显式 ID。但是请注意,如果您在应用程序的整个生命周期中使用数千个 wx.ID_ANYwx.NewID() ID,则自动 ID 可能会环绕 运行.

至于更好的方法,我想我会使用 wx.ID_ANY 然后使用字典将分配给项目的菜单 ID 映射到真实数据对象。这样,ID(实际上只是与 UI 相关联的实现细节,而不是数据模型)本身并没有真正的意义,但它们可以在菜单事件处理程序中使用,以轻松获得真正的意义与应用程序相关的数据。例如:

    item = menu.Append(wx.ID_ANY, "Foo")
    self.menuIdMap[item.GetId()] = someDataObjectForFoo
    self.Bind(wx.EVT_MENU, self.OnMenuItemSelected, item)

然后:

def OnMenuItemSelected(self, evt):
    dataObj = self.menuIdMap[evt.GetId()]
    dataObj.doSomething()