【问题标题】:How to dynamically replace the menubar in wxpython?wxpython中如何动态替换菜单栏?
【发布时间】:2020-06-12 12:02:30
【问题描述】:

我正在使用 wxpython 制作像 AmCap 这样的相机查看器。现在我正在制作一个显示已连接相机列表的菜单栏。(如 AMCAP 设备菜单,见图 1)

这是我的代码:(get_all_devices 返回已连接设备的列表并且工作正常)

class MainFrame(wx.Frame):
    def __init__(self, parent, fid, title, size):
        wx.Frame.__init__(self, parent, fid, title, wx.DefaultPosition, size)

        self.devices = get_all_devices()
        # init menubar
        self.make_menubar()

        # set timer to check usb connectivity
        self.timer = wx.Timer(self)
        self.timer.Start(100) 
        self.Bind(wx.EVT_TIMER, self.check_device)

    def make_menubar(self):
        self.menubar = wx.MenuBar()
        self.devices_menu = wx.Menu()
        self.options_menu = wx.Menu()
        help_menu = wx.Menu()
        self.make_devices_menu()

        self.options_menu.Append(101, 'resolutions')
        self.menubar.Append(self.devices_menu, 'devices')
        self.menubar.Append(self.options_menu, 'options')
        self.menubar.Append(help_menu, 'help')

        self.SetMenuBar(self.menubar)

    def recreate_menubar(self):
        self.menubar.Destroy()
        self.make_menubar()
        self.Layout()
        self.Refresh()

    def make_devices_menu(self):
        for i in range(len(self.devices)):
            self.devices_menu.Append(CI.MENU_DEVICES + 1 + i, self.devices[i], kind=wx.ITEM_CHECK)
            self.Bind(wx.EVT_MENU, self.click_device_menu, id=CI.MENU_DEVICES + 1 +  i)

    def check_device(self, evt):
        cur_devices = get_all_devices()
        if set(self.devices) != set(cur_devices):
            self.devices = cur_devices
            self.recreate_menubar()

一开始它确实有效,但如果我尝试断开和连接相机 4~5 次,它不会重新创建菜单栏。例如,假设有两个连接的摄像头,如图 1。如果我断开第一个摄像头,程序将如图 2 所示。(只剩下一个摄像头)。然后如果我再次连接相机,它将再次显示如图1所示的两个相机。这是我所期望的。(图 1 - 断开连接 -> 图 2 - 连接 -> 图 1)

但实际上,经过 4~5 次后,它就无法正常工作了。它不会更新菜单栏。(图 1 - 断开连接 -> 图 2 - 连接 -> 再次图 2!)

我做错了什么? wxpython中不允许吗?

如果您需要有关我的代码的更多信息,请告诉我。

欢迎任何提示! 提前致谢。

图一

图2

编辑:

我发现如果我在init的最后加上这样的代码:

self.menubar.SetName(str(self.devices))
self.SetMenuBar(self.menubar)
print(self.menubar.GetName())
print(self.GetMenuBar().GetName())

它返回相同的已连接摄像机列表。所以我认为 wxpyhthon 可以正确地制作和设置菜单栏。

【问题讨论】:

    标签: python python-3.x wxwidgets wxpython


    【解决方案1】:

    虽然重新创建整个菜单栏看起来有点过分(您可以只重新创建设备菜单,或者您甚至可以删除旧的相机项目并添加新项目,甚至不这样做),它仍然可以工作。

    您是否检查过您的recreate_menubar() 是否在您期望的时候被调用?您可以从中显示一个消息框来确定。如果它被调用但不知何故没有更新菜单栏,最好的办法是尝试在SSCCE 中重现问题并在wxTrac 上打开票证,以便可以调试并希望修复它(如果您这样做,请提及您的平台)。

    【讨论】:

    • 感谢您的回答,是的,我检查过了。它工作正常。我发现的另一件奇怪的事情是,如果我编写代码来打印菜单栏的 id 并单击错误的菜单栏(当这种情况发生时),它会打印出错误的人的 id。即使我检查了 self.GetMenuBar() 并且它返回了正确的菜单栏 ID(不是错误的,是新的)。现在我不知道发生了什么。我应该接受你的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    • 1970-01-01
    • 1970-01-01
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2011-12-28
    相关资源
    最近更新 更多