wxPython:重定向其他小部件上的事件(TextCtrl)
wxPython: Redirecting events on other widgets (TextCtrl)
案例研究似乎不太难解释,但我猜wxPython中的TextCtrl不经常这样使用。所以这里是:我有一个带有两个 TextCtrl 的简单 window。一个是输入小部件(用户应该在那里输入命令),第二个是输出小部件(系统显示命令的结果)。输出域是一个只读的TextCtrl,只有系统可以写入。
到目前为止一切顺利。现在,我想拦截输出小部件中的事件:如果用户在此输出字段(只读小部件)中键入内容,他们应该被重定向到输入字段,并且他们开始输入的文本应该出现在那里。第一部分并不复杂:我拦截了输出小部件上的 EVT_KEY_DOWN 并可以执行类似 self.input.SetFocus() 的操作。但是,用户按下的键丢失了。如果 he/she 开始打字,她必须重新开始。这应该是一个快捷功能(无论用户在什么字段输入,都应该写在输入小部件中)。
关于我为什么这样做的简短说明,因为它仍然很愚蠢:有视力的用户不会经常使用只读小部件;他们看到他们并让他们独自一人。此应用程序主要是为使用屏幕阅读器的用户设计的,他们必须在输出字段中移动。因此光标经常在那里,按键没有任何效果(因为它是一个只读小部件)。如果用户在输入输出小部件时被重定向到输入字段,并且他输入的文本已经在此小部件中,那就太好了。
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
self.panel = MyPanel(self)
self.Show()
self.Maximize()
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
# Input field
self.input = wx.TextCtrl(self, -1, "", size=(125, -5),
style=wx.TE_PROCESS_ENTER)
# Ouput
self.output = wx.TextCtrl(self, -1, "",
size=(600, 400), style=wx.TE_MULTILINE|wx.TE_READONLY)
# Add the output fields in the sizer
sizer.Add(self.input)
sizer.Add(self.output, proportion=8)
# Event handler
self.output.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
def OnKeyDown(self, e):
"""A key is pressed in the output widget."""
modifiers = e.GetModifiers()
key = e.GetUnicodeKey()
if not key:
key = e.GetKeyCode()
print "From there, we should redirect to the input"
self.input.SetFocus()
# Let's run that
app = wx.App()
MyFrame(None)
app.MainLoop()
self.input.EmulateKeyPress(e)
试一试。如果您在 Windows 上,它应该可以正常工作。在其他平台上它并不完美,但基本上也可以。
其他选项是使用 wx.UiActionSimulator
,或者只是将新字符附加到代码中的输入 textctrl。
案例研究似乎不太难解释,但我猜wxPython中的TextCtrl不经常这样使用。所以这里是:我有一个带有两个 TextCtrl 的简单 window。一个是输入小部件(用户应该在那里输入命令),第二个是输出小部件(系统显示命令的结果)。输出域是一个只读的TextCtrl,只有系统可以写入。
到目前为止一切顺利。现在,我想拦截输出小部件中的事件:如果用户在此输出字段(只读小部件)中键入内容,他们应该被重定向到输入字段,并且他们开始输入的文本应该出现在那里。第一部分并不复杂:我拦截了输出小部件上的 EVT_KEY_DOWN 并可以执行类似 self.input.SetFocus() 的操作。但是,用户按下的键丢失了。如果 he/she 开始打字,她必须重新开始。这应该是一个快捷功能(无论用户在什么字段输入,都应该写在输入小部件中)。
关于我为什么这样做的简短说明,因为它仍然很愚蠢:有视力的用户不会经常使用只读小部件;他们看到他们并让他们独自一人。此应用程序主要是为使用屏幕阅读器的用户设计的,他们必须在输出字段中移动。因此光标经常在那里,按键没有任何效果(因为它是一个只读小部件)。如果用户在输入输出小部件时被重定向到输入字段,并且他输入的文本已经在此小部件中,那就太好了。
import wx
class MyFrame(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent)
self.panel = MyPanel(self)
self.Show()
self.Maximize()
class MyPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
sizer = wx.BoxSizer(wx.VERTICAL)
self.SetSizer(sizer)
# Input field
self.input = wx.TextCtrl(self, -1, "", size=(125, -5),
style=wx.TE_PROCESS_ENTER)
# Ouput
self.output = wx.TextCtrl(self, -1, "",
size=(600, 400), style=wx.TE_MULTILINE|wx.TE_READONLY)
# Add the output fields in the sizer
sizer.Add(self.input)
sizer.Add(self.output, proportion=8)
# Event handler
self.output.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
def OnKeyDown(self, e):
"""A key is pressed in the output widget."""
modifiers = e.GetModifiers()
key = e.GetUnicodeKey()
if not key:
key = e.GetKeyCode()
print "From there, we should redirect to the input"
self.input.SetFocus()
# Let's run that
app = wx.App()
MyFrame(None)
app.MainLoop()
self.input.EmulateKeyPress(e)
试一试。如果您在 Windows 上,它应该可以正常工作。在其他平台上它并不完美,但基本上也可以。
其他选项是使用 wx.UiActionSimulator
,或者只是将新字符附加到代码中的输入 textctrl。