如何使 Tkinter KeyRelease 事件始终提供大写字母?

发布于 2024-12-31 22:38:00 字数 1200 浏览 0 评论 0原文

当我尝试在 Tkinter Text 小部件上使用 KeyRelease 事件时,它有时在 event.char 中提供小写字符,但在文本小部件中显示大写字符。当我轻快地按下 Shift 按钮,然后按下一个字母时,就会发生这种情况。如何使用 Tkinter Text 小部件上的 KeyRelease 事件可靠地捕获大小写正确的字符?

以下是我在 MacBook Pro 上测试的示例代码:

from Tkinter import *

class App:

    def __init__(self):

        # create application window
        self.root = Tk()

        # add frame to contain widgets
        frame = Frame(self.root, width=768, height=576, 
                      padx=20, pady=20, bg="lightgrey")
        frame.pack()

        # add text widget to contain text typed by the user
        self.text = Text(frame, name="typedText", bd="5", wrap=WORD, relief=FLAT)
        self.text.bind("<KeyRelease>", self.printKey)
        self.text.pack(fill=X)

    """
    printKey sometimes prints lowercase letters to the console, 
    but upper case letters in the text widget, 
    especially when I lightly and quickly press Shift and then some letter
    on my MacBook Pro keyboard
    """  
    def printKey(self, event):
        print event.char

    def start(self):
        self.root.mainloop()

def main():
    a = App()
    a.start()

if __name__ == "__main__":
    sys.exit(main())

When I try to use the KeyRelease event on the Tkinter Text widget, it sometimes provides a lowercase character in event.char, but displays an uppercase character in the text widget. This occurs when I lightly and quickly press the shift button and then a letter. How can I reliably capture the correctly cased character with the KeyRelease event on a Tkinter Text widget?

Here's the sample code that I tested on my MacBook Pro:

from Tkinter import *

class App:

    def __init__(self):

        # create application window
        self.root = Tk()

        # add frame to contain widgets
        frame = Frame(self.root, width=768, height=576, 
                      padx=20, pady=20, bg="lightgrey")
        frame.pack()

        # add text widget to contain text typed by the user
        self.text = Text(frame, name="typedText", bd="5", wrap=WORD, relief=FLAT)
        self.text.bind("<KeyRelease>", self.printKey)
        self.text.pack(fill=X)

    """
    printKey sometimes prints lowercase letters to the console, 
    but upper case letters in the text widget, 
    especially when I lightly and quickly press Shift and then some letter
    on my MacBook Pro keyboard
    """  
    def printKey(self, event):
        print event.char

    def start(self):
        self.root.mainloop()

def main():
    a = App()
    a.start()

if __name__ == "__main__":
    sys.exit(main())

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

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

发布评论

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

评论(2

仙女 2025-01-07 22:38:00

发生的情况是您在释放字母键之前释放了 Shift 键。插入字符时会按下 Shift 键,这就是为什么小部件会获得大写字符,但在处理 keyrelease 绑定时,Shift 已经被释放,因此您会看到小写字符。

如果要打印插入的内容,请绑定到按键而不是释放。

What is happening is that you are releasing the shift key before the letter key. The shift is pressed at the time the character is inserted which is why the widget gets an uppercase character, but by the time your keyrelease binding is processed the shift has already been released so you see the lowercase character.

If you want to print what is being inserted, bind to the key press instead of the release.

剑心龙吟 2025-01-07 22:38:00

根据 Bryan 的见解,我修改了代码,它似乎可以工作:

from Tkinter import *
import string

class App:

  def __init__(self):

    # create application window
    self.root = Tk()

    # add frame to contain widgets
    frame = Frame(self.root, width=768, height=576, padx=20, pady=20, bg="lightgrey")
    frame.pack()

    # add text widget to contain text typed by the user
    self.text = Text(frame, name="typedText", bd="5", wrap=WORD, relief=FLAT)
    self.text.bind("<KeyPress>", self.printKey)
    self.text.pack(fill=X)

  """

  this correctly prints the letters when pressed (and does not print the Shift keys)

  """  
  def printKey(self, event):
    # Adapted from http://www.kosbie.net/cmu/fall-10/15-110/koz/misc-demos/src/keyEventsDemo.py
    ignoreSyms = [ "Shift_L", "Shift_R", "Control_L", "Control_R", "Caps_Lock" ]    
    if event.keysym not in ignoreSyms:
      print event.char

  def start(self):
    self.root.mainloop()

def main():
  a = App()
  a.start()

if __name__ == "__main__":
  sys.exit(main())

Based on Bryan's insight, I modified the code and it appears to work:

from Tkinter import *
import string

class App:

  def __init__(self):

    # create application window
    self.root = Tk()

    # add frame to contain widgets
    frame = Frame(self.root, width=768, height=576, padx=20, pady=20, bg="lightgrey")
    frame.pack()

    # add text widget to contain text typed by the user
    self.text = Text(frame, name="typedText", bd="5", wrap=WORD, relief=FLAT)
    self.text.bind("<KeyPress>", self.printKey)
    self.text.pack(fill=X)

  """

  this correctly prints the letters when pressed (and does not print the Shift keys)

  """  
  def printKey(self, event):
    # Adapted from http://www.kosbie.net/cmu/fall-10/15-110/koz/misc-demos/src/keyEventsDemo.py
    ignoreSyms = [ "Shift_L", "Shift_R", "Control_L", "Control_R", "Caps_Lock" ]    
    if event.keysym not in ignoreSyms:
      print event.char

  def start(self):
    self.root.mainloop()

def main():
  a = App()
  a.start()

if __name__ == "__main__":
  sys.exit(main())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文