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。