wxPython - Tratamento de Eventos

Ao contrário de um aplicativo de modo de console, que é executado de maneira sequencial, um aplicativo baseado em GUI é orientado a eventos. Funções ou métodos são executados em resposta às ações do usuário, como clicar em um botão, selecionar um item da coleção ou clicar com o mouse, etc., chamados de eventos.

Os dados relativos a um evento que ocorre durante o tempo de execução do aplicativo são armazenados como objeto de uma subclasse derivada de wx.Event. Um controle de exibição (como Button) é a origem do evento de um tipo específico e produz um objeto da classe Event associado a ele. Por exemplo, clicar em um botão emite um wx.CommandEvent. Esses dados de evento são despachados para o método manipulador de eventos no programa. wxPython possui muitos ligadores de eventos predefinidos. AEvent binder encapsula o relacionamento entre um widget (controle) específico, seu tipo de evento associado e o método do manipulador de eventos.

Por exemplo, para ligar OnClick() method do programa em um evento de clique de botão, a seguinte declaração é necessária -

self.b1.Bind(EVT_BUTTON, OnClick)

Bind() methodé herdado por todos os objetos de exibição da classe wx.EvtHandler. EVT_.BUTTON aqui é o fichário, que associa o evento de clique de botão ao método OnClick ().

Exemplo

No exemplo a seguir, o MoveEvent, causado ao arrastar a janela de nível superior - um objeto wx.Frame, neste caso - está conectado a OnMove() methodusando o fichário wx.EVT_MOVE. O código exibe uma janela. Se for movido com o mouse, suas coordenadas instantâneas são exibidas no console.

import wx
  
class Example(wx.Frame): 
            
   def __init__(self, *args, **kw): 
      super(Example, self).__init__(*args, **kw)  
      self.InitUI() 
           
   def InitUI(self): 
      self.Bind(wx.EVT_MOVE, self.OnMove) 
      self.SetSize((250, 180)) 
      self.SetTitle('Move event') 
      self.Centre() 
      self.Show(True)
		   
   def OnMove(self, e): 
      x, y = e.GetPosition() 
      print "current window position x = ",x," y= ",y 
         
ex = wx.App() 
Example(None) 
ex.MainLoop()

O código acima produz a seguinte saída -

posição atual da janela x = 562 y = 309

posição atual da janela x = 562 y = 309

posição atual da janela x = 326 y = 304

posição atual da janela x = 384 y = 240

posição atual da janela x = 173 y = 408

posição atual da janela x = 226 y = 30

posição atual da janela x = 481 y = 80

Algumas das subclasses herdadas de wx.Event estão listadas na tabela a seguir -

SN Eventos e Descrição
1

wxKeyEvent

Ocorre quando uma tecla é pressionada ou liberada

2

wxPaintEvent

É gerado sempre que o conteúdo da janela precisa ser redesenhado

3

wxMouseEvent

Contém dados sobre qualquer evento devido à atividade do mouse, como botão do mouse pressionado ou arrastado

4

wxScrollEvent

Associado a controles de rolagem como wxScrollbar e wxSlider

5

wxCommandEvent

Contém dados de eventos originados de muitos widgets, como botão, caixas de diálogo, área de transferência, etc.

6

wxMenuEvent

Diferentes eventos relacionados ao menu, exceto clique do botão de comando

7

wxColourPickerEvent

eventos gerados por wxColourPickerCtrl

8

wxDirFilePickerEvent

Eventos gerados por FileDialog e DirDialog

Os eventos em wxPython são de dois tipos. Eventos básicos e eventos de comando. Um evento básico permanece local para a janela em que se origina. A maioria dos wxWidgets gera eventos de comando. UMAcommand event pode ser propagado para a janela ou janelas, que estão acima da janela de origem na hierarquia de classes.

Exemplo

A seguir está um exemplo simples de propagação de eventos. O código completo é -

import wx
  
class MyPanel(wx.Panel): 
     
   def __init__(self, parent): 
      super(MyPanel, self).__init__(parent)
		
      b = wx.Button(self, label = 'Btn', pos = (100,100)) 
      b.Bind(wx.EVT_BUTTON, self.btnclk) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonClicked) 
		
   def OnButtonClicked(self, e): 
         
      print 'Panel received click event. propagated to Frame class' 
      e.Skip()  
		
   def btnclk(self,e): 
      print "Button received click event. propagated to Panel class" 
      e.Skip()
		
class Example(wx.Frame):

   def __init__(self,parent): 
      super(Example, self).__init__(parent)  
         
      self.InitUI() 

   def InitUI(self):
	
      mpnl = MyPanel(self) 
      self.Bind(wx.EVT_BUTTON, self.OnButtonClicked)
		
      self.SetTitle('Event propagation demo') 
      self.Centre() 
      self.Show(True)
		
   def OnButtonClicked(self, e): 
         
      print 'click event received by frame class' 
      e.Skip()
		
ex = wx.App() 
Example(None) 
ex.MainLoop()

No código acima, existem duas classes. MyPanel, uma subclasse wx.Panel e Exemplo, uma subclasse wx.Frame que é a janela de nível superior do programa. Um botão é colocado no painel.

Este objeto Button está vinculado a um manipulador de eventos btnclk () que o propaga para a classe pai (MyPanel neste caso). O clique de botão gera umCommandEvent que pode ser propagado para seu pai pelo método Skip ().

O objeto da classe MyPanel também vincula o evento recebido a outro manipulador OnButtonClicked (). Essa função, por sua vez, transmite para seu pai, a classe Example. O código acima produz a seguinte saída -

Button received click event. Propagated to Panel class. 
Panel received click event. Propagated to Frame class. 
Click event received by frame class.