如何动态替换wxpython中的菜单栏?
How to dynamically replace the menubar in wxpython?
我正在用 wxpython 制作像 AmCap 这样的相机查看器。现在我正在制作一个菜单栏,显示已连接的摄像机列表。(如 AMCAP 设备菜单,见图 1)
这是我的代码:(get_all_devices returns 已连接设备列表,它工作正常)
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中不允许吗?
如果您需要我的代码的更多信息,请告诉我。
欢迎任何提示!
提前致谢。
图 1
图 2
编辑:
我发现如果我在init的末尾添加这样的代码:
self.menubar.SetName(str(self.devices))
self.SetMenuBar(self.menubar)
print(self.menubar.GetName())
print(self.GetMenuBar().GetName())
它 returns 相同的已连接摄像机列表。所以我认为 wxpython 可以正确地制作和设置菜单栏。
我正在用 wxpython 制作像 AmCap 这样的相机查看器。现在我正在制作一个菜单栏,显示已连接的摄像机列表。(如 AMCAP 设备菜单,见图 1)
这是我的代码:(get_all_devices returns 已连接设备列表,它工作正常)
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中不允许吗?
如果您需要我的代码的更多信息,请告诉我。
欢迎任何提示! 提前致谢。
图 1
图 2
编辑:
我发现如果我在init的末尾添加这样的代码:
self.menubar.SetName(str(self.devices))
self.SetMenuBar(self.menubar)
print(self.menubar.GetName())
print(self.GetMenuBar().GetName())
它 returns 相同的已连接摄像机列表。所以我认为 wxpython 可以正确地制作和设置菜单栏。