【问题标题】:wxPython does not trigger key event for accentswxPython 不会触发重音键事件
【发布时间】:2021-06-26 02:52:39
【问题描述】:

我正在尝试创建一个只接受某些键的 wx.TextCtrl。我创建了一个验证函数,并使用 wx.EVT_CHAR 将我的 TextCtrl 绑定到该函数。该功能运行良好,除非我尝试按重音键(´、`、~、¨、^)。我在验证功能的开头放了一个print(event) 以尝试调试它,但是当我按下其中一个键时没有打印任何内容。事件只是没有被触发。

我也试过wx.EVT_KEY_DOWN,但也没有触发。

self.foo_input = wx.TextCtrl(self, size=(150, -1))
self.foo_input.Bind(wx.EVT_CHAR, lambda event: validation_foo(event, foo_params))

这是验证函数(将验证 foo 视为这样):

import wx

def validate_number_key_press(event,
                              negative=False,
                              decimal=False,
                              scientific_notation=False,
                              imaginary=False,
                              decimal_separator='.'):
    key_code = event.GetUnicodeKey()

    print(event)  # for debug
    if ord('0') <= key_code <= ord('9'):
        event.Skip()
        return

    if negative and key_code == ord('-'):
        event.Skip()
        return

    if decimal and key_code == ord(decimal_separator):
        event.Skip()
        return

    if scientific_notation and key_code == ord('e'):
        event.Skip()
        return

    if imaginary and key_code == ord('j'):
        event.Skip()
        return

    # Navigation and deletion
    if key_code in (wx.WXK_BACK, wx.WXK_DELETE, wx.WXK_NUMPAD_DELETE, wx.WXK_TAB, wx.WXK_NUMPAD_TAB, wx.WXK_LEFT, wx.WXK_RIGHT, wx.WXK_NUMPAD_LEFT, wx.WXK_NUMPAD_RIGHT, wx.WXK_HOME, wx.WXK_NUMPAD_HOME, wx.WXK_END, wx.WXK_NUMPAD_END):
        print('Navigation and deletion')  # for debug
        event.Skip()
        return

    return

【问题讨论】:

  • 您是否使用带有死键的键盘布局,即按下'e 会导致é
  • @VZ。按'e 不会产生é。但是,我的键盘选项中有一个“无死键布局”,通过使用它会触发事件。问题是使用这种布局我的键映射错误。 ~ 是按 ] 键打印的,这发生在很多其他键上
  • 那么您使用哪种键盘布局以及在哪种操作系统/环境下使用?
  • Gnu/Linux Pop_OS 20.10 规则:evdev 模型:pc105 布局:br,us 变体:,键盘映射:br-abnt2

标签: python python-3.x validation wxpython wxwidgets


【解决方案1】:

由于您只给了我们一小段代码,请使用以下代码进行测试:
(测试 ["~","`","^"] 作为定义的重音键),看看你是否还有问题。

import wx

class DemoFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY,"Evt_Char Test",
                          size=(600,400)
                          )
        foo_params = ["~","`","^"]
        panel = wx.Panel(self)
        text  = wx.TextCtrl(panel, -1, pos=(10,10))
        text.Bind(wx.EVT_CHAR, self.character)
        text.Bind(wx.EVT_CHAR, lambda event: self.validation_foo(event, foo_params))

    def character(self, event):
        print ("Char keycode : {0}".format(event.GetKeyCode()))
        print ('%c' % event.GetUnicodeKey())
        event.Skip()

    def validation_foo(self, event, params=None):
        print ("Validation keycode : {0}".format(event.GetKeyCode()))
        k = event.GetUnicodeKey()
        if chr(k) in params:
            print("**** Accent key pressed ****", chr(k))

        event.Skip()
        
if __name__ == "__main__":
    app = wx.App()
    mainFrame = DemoFrame()
    mainFrame.Show()
    app.MainLoop()

【讨论】:

  • 嘿。仍然没有被触发......验证函数print(event)中的打印语句没有运行,所以我假设该函数没有被调用,因此,我假设事件没有触发......我添加了验证码函数在我的编辑中,以便您可以看到它。
  • @IsaacYounes 我会非常认真地盯着我的键盘设置。不用说,上面的代码在我的 Linux 机器上运行完美。 TextCtrl 中是否显示“缺失”字符但没有打印任何内容?
  • 是的!我完全复制粘贴了您的代码,但没有打印任何内容。它显示在 TextCtrl 上,但终端上没有打印任何内容。我也在使用Linux机器。也许是我键盘的问题?我不相信它是硬件......它可能是布局?我正在使用 ABNT2
【解决方案2】:

您是否尝试过使用 wx.EVT_CHAR 事件?

例如:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import wx


class MainFrame(wx.Frame):
    def __init__(self, *args, **kwds):
        # MainFrame.__init__
        kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        self.SetSize((506, 373))
        self.txtInput = wx.TextCtrl(self, wx.ID_ANY, style=wx.TE_PROCESS_ENTER)
        self.btnClear = wx.Button(self, wx.ID_ANY, "Clear")
        self.txtResult = wx.TextCtrl(self, wx.ID_ANY, "", style=wx.TE_MULTILINE)        

        self.__set_properties()
        self.__do_layout()

        self.btnClear.Bind(wx.EVT_BUTTON, self.OnBtnClear)
        self.txtInput.Bind(wx.EVT_CHAR, lambda event: self.OnTextEnter(event, []))
        

    def __set_properties(self):
        
        self.SetTitle("Test App")
        self.SetBackgroundColour(wx.Colour(38, 117, 157))
        

    def __do_layout(self):        
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        main_sizer = wx.FlexGridSizer(2, 1, 0, 0)
        grid_sizer_1 = wx.FlexGridSizer(1, 3, 0, 0)
        label_1 = wx.StaticText(self, wx.ID_ANY, "Write something:")
        label_1.SetForegroundColour(wx.Colour(255, 255, 255))
        grid_sizer_1.Add(label_1, 0, wx.ALIGN_CENTER_VERTICAL | wx.LEFT, 10)
        grid_sizer_1.Add(self.txtInput, 0, wx.ALL | wx.EXPAND, 10)
        grid_sizer_1.Add(self.btnClear, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 10)
        grid_sizer_1.AddGrowableCol(1)
        main_sizer.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        main_sizer.Add(self.txtResult, 0, wx.EXPAND, 0)
        main_sizer.AddGrowableRow(1)
        main_sizer.AddGrowableCol(0)
        sizer_1.Add(main_sizer, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        self.Layout()
        self.Centre()       

    def OnTextEnter(self, event, params):        
        self.txtResult.AppendText("You have pressed the key: {}\n".format(event.GetUnicodeKey()))      
        event.Skip()

    def OnBtnClear(self, event):
        self.txtResult.Clear()

# end of class MainFrame

class MyApp(wx.App):
    def OnInit(self):
        self.mainFrame = MainFrame(None, wx.ID_ANY, "")
        self.SetTopWindow(self.mainFrame)
        self.mainFrame.Show()
        return True

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

当您编写任何这些字符(`、¨、´、...)时,都会调用事件处理程序。但请记住,要编写它们,总是需要在它们后面加上一个空格。

因此,您只需检查所介绍的字符是否不是这些数字之一

【讨论】:

  • 我完全尝试了你的代码,但它在我的机器上不起作用:(我开始相信这是一个布局软件的东西,因为我的键盘选项中有一个“无死键布局”,并通过使用它触发事件。问题是使用此布局我的键映射错误。@ 987654324@ 打印按] 键,这发生在很多其他键上。
  • 是的,一定是您的键盘和/或键绑定有问题。你能在另一台电脑/键盘上试试吗?
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 2017-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多