Как динамически заменить menubar в wx python? - PullRequest
1 голос
/ 28 февраля 2020

Я делаю просмотрщик камеры как AmCap с wx python. Сейчас я работаю над созданием меню, которое отображает список подключенных камер (например, меню устройства 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 - отключить -> рис. 2 - подключить -> рис. 1)

Но в действительности, после 4 ~ 5 раз, это не работает должным образом. Меню не обновляется (рис. 1 - отключить -> рис. 2 - подключить -> снова рис. 2!)

Что я сделал не так? Разве это не разрешено в wx python?

Если вам нужна дополнительная информация для моего кода, пожалуйста, дайте мне знать.

любые подсказки будут приветствоваться! заранее спасибо.

enter image description here

рис 1

it

рис 2

Редактировать:

Я обнаружил, что если я добавлю такой код в конце init :

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

возвращает тот же список подключенных камер. Так что, я думаю, wxpyhthon правильно и правильно устанавливает menubar.

1 Ответ

1 голос
/ 29 февраля 2020

Хотя воссоздание всей строки меню выглядит несколько излишне (вы можете воссоздать только меню устройств или вы можете просто удалить старые элементы камеры и добавить новые, даже не делая этого), оно все равно должно работать.

Вы проверили, что ваш recreate_menubar() вызывается, когда вы ожидаете? Вы можете показать окно сообщения от него, чтобы быть уверенным. Если он вызывается, но каким-то образом не обновляет строку меню, лучше всего попытаться воспроизвести проблему в SSCCE и открыть заявку на wxTra c* 1007. * чтобы он мог быть отлажен и, надеюсь, исправлен (пожалуйста, укажите вашу платформу, если вы это сделаете).

...