Fazendo um wxPython TextCtrl responder a cr ou tab
Pergunta
Acho que essa deve ser uma pergunta bem básica, mas pesquisei até a morte no Google sem uma resposta clara, então aqui vai:Eu tenho um TextCtrl e quero uma sequência de eventos bem básica:1) O usuário move o foco para o controle por bem ou por mal.2) O usuário digita algo no TextCtrl.3) O usuário clica em return ou tab.4) Neste ponto, o código captura o texto no TextCtrl, faz algum processamento simples e, em seguida, move o foco para qualquer controle que esteja próximo na ordem de tabulação.
Alguém pode me dizer como fazer isso?Parece tão básico para mim, mas não consigo encontrar a resposta em lugar nenhum.Desculpe se perdi algo óbvio.
Solução
Para que isso funcione corretamente, você precisará capturar os principais eventos e verificar se o usuário pressionou as teclas Enter ou Tab.Como @sundar já mencionado, para que as tabulações funcionem corretamente em todas as plataformas, os widgets precisam ser filhos de um painel.Aqui está um exemplo bastante simples:
import wx
########################################################################
class MyPanel(wx.Panel):
""""""
#----------------------------------------------------------------------
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent)
self.text = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER)
self.text.Bind(wx.EVT_KEY_DOWN, self.onEnter)
btn = wx.Button(self, label="Do something")
self.text.SetFocus()
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.text, 0, wx.EXPAND|wx.ALL, 5)
sizer.Add(btn, 0, wx.ALL|wx.CENTER, 5)
self.SetSizer(sizer)
#----------------------------------------------------------------------
def onEnter(self, event):
""""""
keycode = event.GetKeyCode()
if keycode == wx.WXK_RETURN or keycode == wx.WXK_NUMPAD_ENTER or keycode == wx.WXK_TAB:
self.process_text(event=None)
event.EventObject.Navigate()
event.Skip()
#----------------------------------------------------------------------
def process_text(self, event):
"""
Do something with the text
"""
text = self.text.GetValue()
print text.upper()
for word in text.split():
print word
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title="TextCtrl Demo")
panel = MyPanel(self)
self.Show()
if __name__ == "__main__":
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
Aqui nos ligamos a wx.EVT_KEY_DOWN
e faça com que ele extraia o código-chave que foi pressionado.Em seguida, ele verifica se o código-chave é a tecla Enter ou Tab.Se for, ele chama uma função para processar o texto e depois chama event.EventObject.Navigate()
, o que fará com que wxPython mova o foco para o próximo widget na ordem de guias.
Você pode querer ler o seguinte sobre esse assunto:
- http://wxpython-users.1045709.n5.nabble.com/TextCtrl-processing-enter-key-td5075499.html
- http://www.wxpython.org/docs/api/wx.NavigationKeyEvent-class.html
Para obter mais informações sobre os eventos key e char do wxPython, consulte o seguinte:
Outras dicas
1. Para que a tabulação funcione, a janela ou painel individual em que você coloca controles/perucas deve ter como parte de seu sinalizador de estilo o seguinte:wxTAB_TRAVERSAL ou seja;
class MyPanel(wx.Panel):
def __init__(self, parent,id):
wx.Panel.__init__(self, parent, id, wx.DefaultPosition,wx.DefaultSize,
wx.RAISED_BORDER|wx.TAB_TRAVERSAL)
2.A ordem das guias é definida pela ordem em que você adiciona controles ao painel ou quadro.
3) A ordem de tabulação também parece depender da ordem em que os widgets são criados.Presumo que isso se deva aos números de ID do widget.A ordem de adição aos dimensionadores/painéis não pareceu me ajudar.
4) Aqui está uma pequena demonstração para definir a ordem das guias depois de configurar os controles:
order = (control1, control2, control3, ...)
for i in xrange(len(order) - 1):
order[i+1].MoveAfterInTabOrder(order[i])