wxPython(Phoenix)是否有wx.EVT_CHAR或event.GetKeyCode()等价物?

时间:2014-06-13 15:26:57

标签: python events user-interface event-handling wxpython

我刚刚开始学习Python,所以我试图避免在Python 2中工作太多。目前正在学习使用wxPython的GUI元素。 Python 3文档还没有介绍部分,因此我使用Python 2'入门'文档并在需要时转换为Python 3。

我目前在this section。当在焦点对象上检测到按键时,有一个用于事件处理的wx.EVT_CHAR部分。我在comparison chartCommandEvent docswx.TextCtrl docs中“此类所发送的事件”部分中未看到对它的引用。我已经能够转换大多数其他非Python 3代码,如SizerFlags,但我找不到相应的。

这就是我正在使用的。

import wx
class ExampleFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        baseSizer = wx.BoxSizer(wx.VERTICAL)

        # Create an editable text field
        self.textfield = wx.TextCtrl(self)
        # Attach event handlers to text field
        # Event for when the text changes
        self.Bind(wx.EVT_TEXT, self.OnChange, self.textfield)
        # Event for when a key is pressed, for example an arrow key should fire this event but not the EVT_TEXT event
        self.Bind(wx.EVT_CHAR, self.OnKeyPress, self.textfield)

        # Create a button that will clear the textfield
        clearButton = wx.Button(self, wx.ID_CLEAR, "Clear")
        # Attach event handler on the clearButton to call OnClear()
        self.Bind(wx.EVT_BUTTON, self.OnClear, clearButton)

        # Multiline text field for seeing the events fire
        self.logger = wx.TextCtrl(self, -1, style= wx.TE_MULTILINE | wx.TE_READONLY )

        # Add items to frame sizer
        baseSizer.Add(self.textfield, wx.SizerFlags(0).Expand())
        baseSizer.Add(clearButton, wx.SizerFlags(0).Expand())
        baseSizer.Add(self.logger, wx.SizerFlags(1).Expand())

        # Set sizer for frame
        self.SetSizer(baseSizer)

        # Show 
        self.Show()

    def OnClear(self, e):
        # Clear all text entered into the textfield and return focus
        self.textfield.SetValue("")
        self.textfield.SetFocus()

    def OnChange(self, e):
        # Log every time this event is fired
        self.logger.AppendText("OnChange: " + e.GetString() + '\n')

    def OnKeyPress(self, e):
        # Log every key press in the textfield
        self.logger.AppendText("OnKeyPress: " + e.GetKeyCode() + '\n')

app = wx.App(False)
ExampleFrame(None)
app.MainLoop()

OnChange()会在文本字段中的文本每次更改时触发。 OnKeyPress永远不会发射。如果我确实得到它,我在CommandEvent methods summary中看不到GetKeyCode()等效。

编辑: 由Mike Driscoll解决问题。我实施了他的改变,即改变这一点:

self.Bind(wx.EVT_CHAR, self.OnKeyPress, self.textfield)

到此:

self.textfield.Bind(wx.EVT_CHAR, self.OnKeyPress, self.textfield)  

此外,我必须将e.Skip()添加到OnKeyPress功能中。否则它记录了密钥,但没有在文本字段中添加文本。其他事件很好,没有Skip()将事件从控制树传递给其他侦听器。

1 个答案:

答案 0 :(得分:1)

在这种情况下,您只是错误地绑定了事件。你想要

self.textfield.Bind(wx.EVT_CHAR, self.OnKeyPress, self.textfield)

而不是

self.Bind(wx.EVT_CHAR, self.OnKeyPress, self.textfield)

这是在上下文中:

import wx
class ExampleFrame(wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__(self, parent)
        baseSizer = wx.BoxSizer(wx.VERTICAL)

        # Create an editable text field
        self.textfield = wx.TextCtrl(self)
        # Attach event handlers to text field
        # Event for when the text changes
        self.Bind(wx.EVT_TEXT, self.OnChange, self.textfield)
        # Event for when a key is pressed, for example an arrow key should fire this event but not the EVT_TEXT event
        self.textfield.Bind(wx.EVT_CHAR, self.OnKeyPress, self.textfield)

        # Create a button that will clear the textfield
        clearButton = wx.Button(self, wx.ID_CLEAR, "Clear")
        # Attach event handler on the clearButton to call OnClear()
        self.Bind(wx.EVT_BUTTON, self.OnClear, clearButton)

        # Multiline text field for seeing the events fire
        self.logger = wx.TextCtrl(self, -1, style= wx.TE_MULTILINE | wx.TE_READONLY )

        # Add items to frame sizer
        baseSizer.Add(self.textfield, 1, flag=wx.EXPAND)
        baseSizer.Add(clearButton,0)
        baseSizer.Add(self.logger, 1, flag=wx.EXPAND)

        # Set sizer for frame
        self.SetSizer(baseSizer)

        # Show 
        self.Show()

    def OnClear(self, e):
        # Clear all text entered into the textfield and return focus
        self.textfield.SetValue("")
        self.textfield.SetFocus()
        e.Skip()

    def OnChange(self, e):
        # Log every time this event is fired
        self.logger.AppendText("OnChange: " + e.GetString() + '\n')
        e.Skip()

    def OnKeyPress(self, e):
        # Log every key press in the textfield
        self.logger.AppendText("OnKeyPress: " + str(e.GetKeyCode()) + '\n')
        e.Skip()

app = wx.App(False)
ExampleFrame(None)
app.MainLoop()

您可能希望阅读以下关于差异绑定方法的wiki条目:

至于你的另一个问题,虽然我无法确定,但如果OnKeyPress在凤凰城不存在,我会感到非常惊讶。即使它不在文档中,我也会试一试,因为我猜它还在那里。