Рубрики
Без рубрики

wxpython: учиться сосредоточиться

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

У меня была запрос на этой неделе, чтобы записать быстрое руководство по фокусированным событиям в wxpython Отказ К счастью, на эту тему не было много материалов, поэтому это должно быть довольно быстрым и грязным маленьким постом. Увидимся после прыжка!

Существует действительно только два фокусных события, которые я когда-либо видел использовал: wx.evt_set_focus и wx.evt_kill_focus. Событие, evt_set_focus, уволено, когда виджет получает фокус, например, когда вы нажимаете на пустую панель или поместите курсор внутри виджета TextCtrl. Когда вы вкладываете или выберите из виджета, который имеет фокус, то EVT_KILL_FOCUS уволен.

Один из немногих «gotchas», который я видел, упомянул на списке рассылки WXPYPHON, заключается в том, что WX.Panel принимает только в фокусе, когда он делает не иметь детский виджет, который может принять фокус. Лучший способ объяснить это с серией примеров.

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Focus Tutorial 1")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)        
        
    def onFocus(self, event):
        print "panel received focus!"
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

Теперь этот код отобразит пустую панель с ним. Вы заметите, что Stdout сразу получит «Панель получил фокус!» напечатано к нему. Теперь, если мы добавим кнопку TextCtrl или кнопку, то они получат фокус, а обработчик событий Onfocus не будет выпущен. Попробуйте запустить код ниже, чтобы увидеть это в действии:

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Focus Tutorial 1a")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)
        txt = wx.TextCtrl(panel, wx.ID_ANY, "")
        
    def onFocus(self, event):
        print "panel received focus!"
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

Просто для удовольствия Попробуйте поместить элемент управления Statictext там вместо TextCtrl. Что вы ожидаете, получит фокус? Если вы догадались, что элемент управления Statictext или панель, вы ошиблись! На самом деле, это рамка, которая получает фокус! Робин Данн иллюстрировал это мне, добавив таймер к моему коду. Проверьте это:

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Focus Finder")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        panel.Bind(wx.EVT_SET_FOCUS, self.onFocus)
        txt = wx.StaticText(panel, wx.ID_ANY, 
                   "This label cannot receive focus")

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onTimer)
        self.timer.Start(1000)
                
    def onFocus(self, event):
        print "panel received focus!"

    def onTimer(self, evt):
        print 'Focused window:', wx.Window.FindFocus()
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

Вам может быть интересно, почему вы хотите знать, когда кадр был в фокусе. Это может быть полезно, если вам нужно знать, когда кто-то нажал на свое приложение или принес определенный кадр на передний план. Конечно, некоторые люди предпочли бы знать, когда мышь поступает в рамку, и эта информация может быть с EVT_enter_Window (которую я не буду скрывать здесь).

Теперь давайте посмотрим на wx.evt_kill_focus. Я создал простой пример только с двумя элементами управления. Попробуйте угадать, что произойдет, если вы вкладка между ними.

import wx
 
class MyForm(wx.Frame):
 
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, "Focus Tutorial 1a")
 
        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        
        txt = wx.TextCtrl(panel, wx.ID_ANY, "")
        txt.Bind(wx.EVT_SET_FOCUS, self.onFocus)
        txt.Bind(wx.EVT_KILL_FOCUS, self.onKillFocus)
        btn = wx.Button(panel, wx.ID_ANY, "Test")
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(txt, 0, wx.ALL, 5)
        sizer.Add(btn, 0, wx.ALL, 5)
        panel.SetSizer(sizer)
        
    def onFocus(self, event):
        print "widget received focus!"
        
    def onKillFocus(self, event):
        print "widget lost focus!"
 
# Run the program
if __name__ == "__main__":
    app = wx.PySimpleApp()
    frame = MyForm().Show()
    app.MainLoop()

Поскольку вы, вероятно, предполагали, как вы вкладка между ними, TextCtrl является либо увольнением фокуса убийства, либо событие набора фокусировки. Откуда вы знаете, какой виджет уводит эти события? Посмотрите на мои методы связывания. Только текстовое управление связано с фокусировкой событий. В качестве упражнения попробуйте привязать кнопку для этих обработчиков, и распечатайте, какой виджет стреляет в то, что.

Последнее событие фокусировки я собираюсь упомянуть, является WX.EVT_CHILD_FOCUS, то, что я никогда не использовал. Это событие используется для определения, когда детский виджет получил фокус и выяснить, какой ребенок это. По словам Робин Данн wx.lib.scrolledPanel использует это событие. Один из моих читателей рассказал мне о удобном использовании для WX.EVT_CHILD_FOCUS: Вы можете использовать его на кадре, чтобы просто очистить статусную панель, когда вы нажимаете любой другой виджет для детей. Это Способ у вас нет старого сообщения «Ошибка» сообщения или сумма такого текста в статус-панели, когда вы нажмете другой детский виджет. (hattip @devplayer)

Также обратите внимание, что некоторые из более сложных виджетов имеют свой собственный фокус Hokus Pokus. См. Следующую нить о том, как получить фокус в WX.GRID.GRID Cell: http://www.velocityreviews.com/forums/t352017-wxgrid-and-focus-event.html

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

Дополнительная информация

Загрузки

  • Focusexamples (ZIP)
  • Focusexamples (TAR)