Поймайте нажатие клавиши с помощью таблиц ускорителей, не препятствуя вводу текстовых элементов управления

#python #wxpython

#python #wxpython

Вопрос:

Я пытаюсь использовать таблицу ускорителей, чтобы перехватывать нажатие клавиши глобально в окне, чтобы я мог запустить метод в ответ. Однако таблица ускорителей, похоже, уничтожает событие, которое в противном случае было бы создано нажатием клавиши, не позволяя мне вводить его в текстовые элементы управления. Есть ли какой-нибудь способ обойти это поведение или какое-то другое решение моей проблемы?

Редактировать: Вот лучший пример такого рода ситуации:

 class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(-1,-1))
        ...
            randomId = wx.NewId()
        parent.Bind(wx.EVT_MENU, self.onKey, id=randomId)
        accTable = wx.AcceleratorTable([(wx.ACCEL_NORMAL, 96, randomId)]) # 96 is the keycode for `
        self.SetAcceleratorTable(accTable)
        ...

class ctrlpanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        ...
            grid = wx.GridBagSizer(hgap=7, vgap=7)

        self.lblfreq = wx.StaticText(self, label="Base Frequency (hz): ")
        grid.Add(self.lblfreq, pos=(0,0))
        self.freq = wx.TextCtrl(self, value="0", size=(100, 20))
        grid.Add(self.freq, pos=(0,1))

            self.waveList = ['Sine', 'Semicircle', 'Saw', 'Square']
        self.lblwave = wx.StaticText(self, label="Wave Shape: ")
        grid.Add(self.lblwave, pos=(1,0))
        self.wave = wx.Choice(self, choices=self.waveList)
        self.wave.SetStringSelection('Sine')
        grid.Add(self.wave, pos=(1,1))

        self.SetSizerAndFit(grid)
  

С этим кодом таблица ускорителей работает отлично, подбирая мои нажатия клавиш везде, где фокус находится в окне, и активируя метод OnKey. Однако, когда основное внимание уделяется текстовому элементу управления, я не могу ввести символ, который я выбираю, в текстовый элемент управления, потому что таблица ускорителей обрабатывает это событие до того, как оно отправится куда-либо еще, или предотвращает запуск или распространение обычного события. Я хочу иметь возможность сделать так, чтобы событие все еще происходило нормально, поэтому текст будет отображаться в текстовом элементе управления при вводе, даже если эти клавиши настроены на выполнение какого-либо другого действия, обычно в окне. Есть ли какой-либо тип event.Skip (), который я мог бы использовать здесь?

Комментарии:

1. Можете ли вы предоставить небольшой пример кода, который демонстрирует проблему?

Ответ №1:

Трудно сказать, в чем проблема, без дополнительной информации, такой как ОС, версия wx или небольшой пример, показывающий проблему. Однако вот пара примеров статей на эту тему, которые могут помочь вам разобраться в проблеме:

http://www.blog.pythonlibrary.org/2008/07/02/wxpython-working-with-menus-toolbars-and-accelerators/

http://www.blog.pythonlibrary.org/2010/12/02/wxpython-keyboard-shortcuts-accelerators/

Комментарии:

1. Я уже просмотрел эти страницы. Они помогли мне понять, как использовать таблицу ускорителей, но у них нет информации о моей текущей проблеме, которая позволяет моим элементам управления нормально обрабатывать ключевые события после того, как с ними будет выполнена таблица ускорителей.

2. Возможно, вам потребуется вызвать event.Skip() в конце обработчика

3. Это не работает, потому что событие, переданное обработчику, является не KeyEvent, которое обычно создается, а MenuEvent, как указано. Кроме того, исходный KeyEvent будет привязан к самому TextCtrl, не так ли? Я не знаю никакого способа получить доступ к исходному KeyEvent, или если он вообще существует где-либо. В этом проблема.