捕获 TextCtrl 的键/字符事件并将键入的键转发到子进程的标准输入

发布于 2024-10-15 09:17:13 字数 948 浏览 2 评论 0原文

我试图使用 wx.TextCtrl 捕获键入的按键事件,并将键入的按键直接转发到子进程的标准输入。请注意,出于我的特殊目的,我将 完全禁用 TextCtrl 的文本编辑功能。即,当我输入一封信时, 该信件不会出现在TextCtrl上,它会被直接转发。
这是一些代码来说明我想要的。

# inside the main frame
    self.text = wx.TextCtrl(self.panel, wx.ID_ANY, style=wx.TE_MULTILINE)
    self.text.Bind(wx.EVT_KEY_DOWN, self.OnKey)
    self.text.Bind(wx.EVT_CHAR, self.OnChar)
# ...

def OnKey(self, evt):
    keycode = evt.GetKeyCode()
    # ENTER

    if keycode == 13:
        self.subprocess.stdin.read("\n") 
    if keycode == 9:
        self.subprocess.stdin.read("\t") 
    if keycode == 8:
        self.subprocess.stdin.read("\b") 
    if keycode == 316:
        pass # maybe some key will be ignored
    else:
        evt.skip()

def OnChar(self, evt):
    key=chr(keycode)                   
    self.subprocess.stdin.read(key)

我想将“ENTER”、“TAB”、“BACKSPACE”、字符、数字等所有按键输入事件转发到stdin,而不让TextCtrl干扰。有没有好的办法呢?或者我必须一一明确地匹配每个键?

感谢您的任何建议!

I am trying to use wx.TextCtrl to catch the typed key events, and directly forward the typed key to the stdin of a subprocess. Please note, for my special purpose, I will
completely disable the text editing feature of the TextCtrl. i.e., when I type a letter,
the letter will not be appearing on the TextCtrl, it will be directly forwarded.
Here is some code to illustrate what I want.

# inside the main frame
    self.text = wx.TextCtrl(self.panel, wx.ID_ANY, style=wx.TE_MULTILINE)
    self.text.Bind(wx.EVT_KEY_DOWN, self.OnKey)
    self.text.Bind(wx.EVT_CHAR, self.OnChar)
# ...

def OnKey(self, evt):
    keycode = evt.GetKeyCode()
    # ENTER

    if keycode == 13:
        self.subprocess.stdin.read("\n") 
    if keycode == 9:
        self.subprocess.stdin.read("\t") 
    if keycode == 8:
        self.subprocess.stdin.read("\b") 
    if keycode == 316:
        pass # maybe some key will be ignored
    else:
        evt.skip()

def OnChar(self, evt):
    key=chr(keycode)                   
    self.subprocess.stdin.read(key)

I want to forward "ENTER", "TAB", "BACKSPACE", characters, numbers, etc., all the key input events to stdin, without letting TextCtrl to interfere. Is there a good way to do it? Or I have to explicitely match each key one by one?

Thanks for any suggestions!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情丝乱 2024-10-22 09:17:13

您可以执行此操作将键代码转换为字符:

chr(keycode)

但这并不能获得所有内容,例如输入和制表符。您必须根据具体情况进行处理(就像您在示例中所做的那样)。否则,您需要创建一个键代码到字符映射的字典:

codemap = {97:'a', 98:'b', 8:'\b'} # Fill this out
self.subprocess.stdin.read(codemap[keycode])

您可能还想使用 wx.TE_PROCESS_ENTER 和 wx.TE_PROCESS_TAB。它们启用/禁用将 Enter 和 Tab 键捕获为文本。

You can do this to convert the key code to a character:

chr(keycode)

That won't get everything though, like enters and tabs. You'd have to handle that on a case by case basis (like you do in your example). Otherwise you'll need to create a dictionary of key code to character mappings:

codemap = {97:'a', 98:'b', 8:'\b'} # Fill this out
self.subprocess.stdin.read(codemap[keycode])

You also might want to play with wx.TE_PROCESS_ENTER and wx.TE_PROCESS_TAB. They enable/disable capturing the enter and tab keys as text.

谎言月老 2024-10-22 09:17:13

在这里你可以找到“key”python模块上的一些修饰符和键状态:

https:/ /pythonhosted.org/pyglet/programming_guide/keyboard_events.html

您只能使用 1 个活页夹,例如 @KEY_DOWN,而不能同时使用 @KEY_DOWN 和 EVT_CHAR

要操作字符,您需要检查值的范围,但使用上的信息例如,您可以在上面的网站上执行以下操作:

key.A

识别“a”。

否则,您可以通过关联的键码(unicode 或 ASCII)来识别“a”。

您需要从“evt”KeyEvent 获取:

evt.GetRawKeyCode()

要识别用按键按下的修饰符,例如 SHIFT 和 CTRL SX ecc:

evt.GetModifiers()

这里,作为“key”模块的使用示例,我制作了一个使 TextCtrl 接受的侦听器仅输入数值。如果需要,您可以修改它。
对于字母,您需要检查以下来源的数值:
65(A)至90(Z)和97(a)至122(z)。
你可以使用:

evt.GetUnicodeKey()

但也

evt.GetRawKeyCode()

可以。
所以你将拥有:

rawKey = evt.GetRawKeyCode()
if rawKey >= 65 and rawKey <= 90 and rawKey >= 97 and rawKey <= 122:
      # Inserted a letter from the alphabet.

##########

from pyglet.window import key
from Utils.NumberUtils import NumberUtils

ENTRY_ID = "id"
ENTRY_KEY_EVENT = "keyEvent"
ENTRY_SELECTION_EVENT = "selectionEvent"

MASK_STARTED_RIGHT_SELECTION = 1
MASK_STARTED_LEFT_SELECTION = -1

class KeyboardEventUtils(object):

    __mLastEvt = {}

    def on_change_text_check_is_float_value(self, evt):
        txt = evt.GetEventObject()
        strng = txt.GetValue()
        rawKey = evt.GetRawKeyCode()
        modifiers = evt.GetModifiers()

        if KeyboardEventUtils.__mLastEvt != None and len(KeyboardEventUtils.__mLastEvt) > 0 and KeyboardEventUtils.__mLastEvt[ENTRY_ID] != txt.GetId():
            self._mLastEvt = {}

        if chr(rawKey).isnumeric() or (rawKey == key.PERIOD and not chr(rawKey) in strng and len(strng) > 0) or (rawKey == key.MINUS and not chr(rawKey) in strng and (len(strng) == 0 or txt.GetInsertionPoint() == 0)):
            pos = txt.GetInsertionPoint()
            txt.SetValue(str(float(txt.GetValue()[:pos] + chr(rawKey) + txt.GetValue()[pos:])))
            txt.SetInsertionPoint(pos + 1)

        elif (modifiers == 4 or modifiers == key.MOD_SHIFT) and rawKey == key.LEFT:             # 4 (?) key.MOD_SHIFT (?)
            pos = txt.GetInsertionPoint()
            rng = list(txt.GetSelection())

            if rng[0] == rng[1] and ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt:
                del KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT]

            if ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt and KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] == MASK_STARTED_RIGHT_SELECTION:

                rng[1] = rng[1] - 1
            else:
                KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] = MASK_STARTED_LEFT_SELECTION
                rng[0] = rng[0] - 1

            txt.SetSelection(rng[0], rng[1])

        elif (modifiers == 4 or modifiers == key.MOD_SHIFT):                                    # 4 (?) key.MOD_SHIFT (?)
            pos = txt.GetInsertionPoint()
            rng = list(txt.GetSelection())

            if rng[0] == rng[1] and ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt:
                del KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT]

            if ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt and KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] == MASK_STARTED_LEFT_SELECTION:
                rng[0] = rng[0] + 1
            else:
                KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] = MASK_STARTED_RIGHT_SELECTION
                rng[1] = rng[1] + 1

            txt.SetSelection(rng[0], rng[1])

        elif rawKey == key.LEFT:
            rng = list(txt.GetSelection())

            if rng[0] != rng[1]:
                txt.SetInsertionPoint(rng[0])
            else:
                txt.SetInsertionPoint(txt.GetInsertionPoint() - 1)

        elif rawKey == key.RIGHT:
            rng = list(txt.GetSelection())

            if rng[0] != rng[1]:
                txt.SetInsertionPoint(rng[1])
            else:
                txt.SetInsertionPoint(txt.GetInsertionPoint() + 1)

        elif rawKey == key.UP or rawKey == key.DOWN:
            pass

        elif rawKey == key.BACKSPACE:                                              
            pos = txt.GetInsertionPoint()
            if txt.GetStringSelection() == "":
                txt.SetValue(txt.GetValue()[:pos-1] + txt.GetValue()[pos:])
                txt.SetInsertionPoint(pos - 0x1)
            else:
                r = txt.GetSelection()
                txt.SetValue(txt.GetValue()[:r[0]] + txt.GetValue()[r[1]:])
                txt.SetInsertionPoint(pos)

        elif rawKey == key.DELETE:
            pos = txt.GetInsertionPoint()
            if txt.GetStringSelection() == "":
                txt.SetValue(txt.GetValue()[:pos] + txt.GetValue()[pos+1:])
            else:
                r = txt.GetSelection()
                txt.SetValue(txt.GetValue()[:r[0]] + txt.GetValue()[r[1]:])
            txt.SetInsertionPoint(pos)

        elif modifiers == key.MOD_CTRL and rawKey == key.A:
            txt.SelectAll()

        else:

            KeyboardEventUtils.__mLastEvt[ENTRY_ID] = txt.GetId()
            KeyboardEventUtils.__mLastEvt[ENTRY_KEY_EVENT] = evt
            return False

        KeyboardEventUtils.__mLastEvt[ENTRY_ID] = txt.GetId()
        KeyboardEventUtils.__mLastEvt[ENTRY_KEY_EVENT] = evt
        return True

here you can find some of the modifiers and key states on the "key" python module:

https://pythonhosted.org/pyglet/programming_guide/keyboard_events.html

You can only use 1 binder, like @KEY_DOWN and not both @KEY_DOWN and EVT_CHAR

To manipulate chars you need to check the range of values but using the infos on the website above you can, for example do:

key.A

TO identify "a".

Otherwise you can identify "a" by the keycode associated (unicode or ASCII).

You need to get from the "evt" KeyEvent the:

evt.GetRawKeyCode()

To identify modifiers like SHIFT and CTRL SX ecc pressed with the key:

evt.GetModifiers()

Here, as an example of the usage of the "key" module, a listener I made that makes a TextCtrl accept only numerical values iput. You can modify it if you want.
For letters you need to check for numerical values from:
65 (A) to 90 (Z) and from 97 (a) to 122 (z).
And u can use:

evt.GetUnicodeKey()

But also

evt.GetRawKeyCode()

Works.
So you will have:

rawKey = evt.GetRawKeyCode()
if rawKey >= 65 and rawKey <= 90 and rawKey >= 97 and rawKey <= 122:
      # Inserted a letter from the alphabet.

###########

from pyglet.window import key
from Utils.NumberUtils import NumberUtils

ENTRY_ID = "id"
ENTRY_KEY_EVENT = "keyEvent"
ENTRY_SELECTION_EVENT = "selectionEvent"

MASK_STARTED_RIGHT_SELECTION = 1
MASK_STARTED_LEFT_SELECTION = -1

class KeyboardEventUtils(object):

    __mLastEvt = {}

    def on_change_text_check_is_float_value(self, evt):
        txt = evt.GetEventObject()
        strng = txt.GetValue()
        rawKey = evt.GetRawKeyCode()
        modifiers = evt.GetModifiers()

        if KeyboardEventUtils.__mLastEvt != None and len(KeyboardEventUtils.__mLastEvt) > 0 and KeyboardEventUtils.__mLastEvt[ENTRY_ID] != txt.GetId():
            self._mLastEvt = {}

        if chr(rawKey).isnumeric() or (rawKey == key.PERIOD and not chr(rawKey) in strng and len(strng) > 0) or (rawKey == key.MINUS and not chr(rawKey) in strng and (len(strng) == 0 or txt.GetInsertionPoint() == 0)):
            pos = txt.GetInsertionPoint()
            txt.SetValue(str(float(txt.GetValue()[:pos] + chr(rawKey) + txt.GetValue()[pos:])))
            txt.SetInsertionPoint(pos + 1)

        elif (modifiers == 4 or modifiers == key.MOD_SHIFT) and rawKey == key.LEFT:             # 4 (?) key.MOD_SHIFT (?)
            pos = txt.GetInsertionPoint()
            rng = list(txt.GetSelection())

            if rng[0] == rng[1] and ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt:
                del KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT]

            if ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt and KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] == MASK_STARTED_RIGHT_SELECTION:

                rng[1] = rng[1] - 1
            else:
                KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] = MASK_STARTED_LEFT_SELECTION
                rng[0] = rng[0] - 1

            txt.SetSelection(rng[0], rng[1])

        elif (modifiers == 4 or modifiers == key.MOD_SHIFT):                                    # 4 (?) key.MOD_SHIFT (?)
            pos = txt.GetInsertionPoint()
            rng = list(txt.GetSelection())

            if rng[0] == rng[1] and ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt:
                del KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT]

            if ENTRY_SELECTION_EVENT in KeyboardEventUtils.__mLastEvt and KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] == MASK_STARTED_LEFT_SELECTION:
                rng[0] = rng[0] + 1
            else:
                KeyboardEventUtils.__mLastEvt[ENTRY_SELECTION_EVENT] = MASK_STARTED_RIGHT_SELECTION
                rng[1] = rng[1] + 1

            txt.SetSelection(rng[0], rng[1])

        elif rawKey == key.LEFT:
            rng = list(txt.GetSelection())

            if rng[0] != rng[1]:
                txt.SetInsertionPoint(rng[0])
            else:
                txt.SetInsertionPoint(txt.GetInsertionPoint() - 1)

        elif rawKey == key.RIGHT:
            rng = list(txt.GetSelection())

            if rng[0] != rng[1]:
                txt.SetInsertionPoint(rng[1])
            else:
                txt.SetInsertionPoint(txt.GetInsertionPoint() + 1)

        elif rawKey == key.UP or rawKey == key.DOWN:
            pass

        elif rawKey == key.BACKSPACE:                                              
            pos = txt.GetInsertionPoint()
            if txt.GetStringSelection() == "":
                txt.SetValue(txt.GetValue()[:pos-1] + txt.GetValue()[pos:])
                txt.SetInsertionPoint(pos - 0x1)
            else:
                r = txt.GetSelection()
                txt.SetValue(txt.GetValue()[:r[0]] + txt.GetValue()[r[1]:])
                txt.SetInsertionPoint(pos)

        elif rawKey == key.DELETE:
            pos = txt.GetInsertionPoint()
            if txt.GetStringSelection() == "":
                txt.SetValue(txt.GetValue()[:pos] + txt.GetValue()[pos+1:])
            else:
                r = txt.GetSelection()
                txt.SetValue(txt.GetValue()[:r[0]] + txt.GetValue()[r[1]:])
            txt.SetInsertionPoint(pos)

        elif modifiers == key.MOD_CTRL and rawKey == key.A:
            txt.SelectAll()

        else:

            KeyboardEventUtils.__mLastEvt[ENTRY_ID] = txt.GetId()
            KeyboardEventUtils.__mLastEvt[ENTRY_KEY_EVENT] = evt
            return False

        KeyboardEventUtils.__mLastEvt[ENTRY_ID] = txt.GetId()
        KeyboardEventUtils.__mLastEvt[ENTRY_KEY_EVENT] = evt
        return True
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文