当前位置: 首页 > 知识库问答 >
问题:

检查tkinter中是否按了修改器键

慕容兴贤
2023-03-14

我知道并使用了很多绑定的语法,但是我怎么能直接检查事件对象并提取被按下的字母,例如'c'和修饰词,例如'Control'和'Alt'?

我试过这个

def reportEvent(event):
        eventDict = {
                '2': 'KeyPress', '3': 'KeyRelease', '4': 'ButtonPress', '5': 'ButtonRelease', '6': 'Motion', '7': 'Enter',
                '8': 'Leave', '9': 'FocusIn', '10': 'FocusOut', '12': 'Expose', '15': 'Visibility', '17': 'Destroy',
                '18': 'Unmap', '19': 'Map', '21': 'Reparent', '22': 'Configure', '24': 'Gravity', '26': 'Circulate',
                '28': 'Property', '32': 'Colormap','36': 'Activate', '37': 'Deactivate'}

        rpt = '\n\n%s' % (80*'=')
        rpt = '%s\nEvent: type=%s (%s)' % (rpt, event.type,eventDict.get(event.type, 'Unknown'))
        rpt = '%s\ntime=%s' % (rpt, event.time)
        rpt = '%s widget=%s' % (rpt, event.widget)
        rpt = '%s x=%d, y=%d'% (rpt, event.x, event.y)
        rpt = '%s x_root=%d, y_root=%d' % (rpt, event.x_root, event.y_root)
        rpt = '%s y_root=%d' % (rpt, event.y_root)
        rpt = '%s\nserial=%s' % (rpt, event.serial)
        rpt = '%s num=%s' % (rpt, event.num)
        rpt = '%s height=%s' % (rpt, event.height)
        rpt = '%s width=%s' % (rpt, event.width)
        rpt = '%s keysym=%s' % (rpt, event.keysym)
        rpt = '%s ksNum=%s' % (rpt, event.keysym_num)
        #### Some event types don't have these attributes
        try:
                rpt = '%s focus=%s' % (rpt, event.focus)
        except:
                try:
                        rpt = '%s send=%s' % (rpt, event.send_event)
                except:
                        pass
        print rpt

偷到Python和Tkinter编程,但它没有显示我正在按的最终修饰符

共有3个答案

宗啸
2023-03-14

下面的脚本纠正了之前答案中使用的不正确的位标记,并考虑到ex: state=Shift|Alt|Control不会与修改器判决中的任何内容相匹配。它需要被处理为位标记和匹配位对位。

任何用户需要考虑的是,所有的锁密钥(如果打开)将在事件中被报告。说明你是否要求它。举个例子:你打开了CapsLock和NumLock并试图捕获Alt Control~你实际上会得到“CapsLock NumLock Control Alt”。最简单的方法就是从修改器dict中删除所有ModN键。

据我所知,只能通过keysym属性捕获特定的_L和_R密钥。state属性将始终包含该键的泛型修饰符位标记。

#python 3.8
from tkinter import *

root = Tk()

Modifier = {
    0x1    : 'Shift'        ,
    0x2    : 'CapsLock'     ,
    0x4    : 'Control'      ,
    0x8    : 'NumLock'      ,   #Mod1
    0x10   : 'Mod2'         ,   #?
    0x20   : 'ScrollLock'   ,   #Mod3
    0x40   : 'Mod4'         ,   #?
    0x80   : 'Mod5'         ,   #?
    0x100  : 'Button1'      ,
    0x200  : 'Button2'      ,
    0x400  : 'Button3'      ,
    0x800  : 'Button4'      ,
    0x1000 : 'Button5'      ,
    0x20000: 'Alt'          ,   #not a typo
}

root.bind( '<Key>', lambda e: print(' + '.join([v for k, v in Modifier.items() if k & e.state])))
root.mainloop()

EventType是一个枚举。不需要创建重复此枚举的整个dict。您可以使用event获取EventType的名称。类型名称,并使用事件访问该值。类型价值如果必须将枚举克隆为dict,则可以使用以下方法更彻底(更容易)地完成:

#python 3.8
# EventType Lookup
BindMap = {i.name:i.value for i in EventType}

# A few aliases that wont be returned from the generator
BindMap['Key']      = '2'
BindMap['Button']   = '4'
BindMap['Double']   = '4'
BindMap['Triple']   = '4'
邢献
2023-03-14

在彼得·瓦罗(Peter Varo)的想法的帮助下,我让它为我工作(运行windows 10和python 3.4)。

from tkinter import *

def onKeyDown(e):
    # The obvious information
    c = e.keysym
    s = e.state

    # Manual way to get the modifiers
    ctrl  = (s & 0x4) != 0
    alt   = (s & 0x8) != 0 or (s & 0x80) != 0
    shift = (s & 0x1) != 0

    # Merge it into an output
    # if alt:
    #     c = 'alt+' + c
    if shift:
        c = 'shift+' + c
    if ctrl:
        c = 'ctrl+' + c
    print(c)

# Run the tk window
root = Tk()
root.bind('<Key>', onKeyDown)
root.mainloop()

alt键在我的情况下是错误的(它总是被按下),但是ctrlshift工作正常。

请注意,第一次按下ctrlshift键时,它会将其注册为主键,而不是修改器。只有在稍后按住它时,它才会成为修改器。

因此,您确实需要按组合键(如Ctrl a)。因此,按a,然后按ctrl将产生一个稍微奇怪的结果(它将忽略a并将ctrl标记为主键,而不是修改器)。

华凡
2023-03-14

理论上,这将是你问题的答案:

from tkinter import *

root = Tk()

mods = {
    0x0001: 'Shift',
    0x0002: 'Caps Lock',
    0x0004: 'Control',
    0x0008: 'Left-hand Alt',
    0x0010: 'Num Lock',
    0x0080: 'Right-hand Alt',
    0x0100: 'Mouse button 1',
    0x0200: 'Mouse button 2',
    0x0400: 'Mouse button 3'
}

root.bind( '<Key>', lambda e: print( 'Key:', e.char,
                                     'Mods:', mods.get( e.state, None )))

root.mainloop()

然而,它并没有发挥应有的作用——或者至少在我的110键匈牙利苹果键盘上没有。。

无论如何,这里是事件对象的所有属性:http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/event-handlers.html

 类似资料:
  • 我有一个Java函数,我想在其中测试控制键是否被按住。我该怎么做? 编辑:我正在使用摆动作为gui。

  • 问题内容: 我正在使用Qt Designer构建UI,并且我希望按钮使用不同的修饰符执行不同的操作。因此,我认为我可以调用具有动态字符串属性的函数,这些函数将根据修饰符执行操作。 如果有人知道更简单的方法,我将不胜感激。 问题答案: 看起来您需要做的就是检查按钮处理程序中的keyboardModifiers,并根据需要选择其他操作。可以对各种修饰符进行“或”运算以检查多键组合: PyQt5 : P

  • 问题内容: 在Java中,我有一个程序需要连续检查用户是否按下了键。所以在伪代码中,像 提前致谢! 问题答案: 在Java中,你不检查是否有键被按下,而不是你听到秒。实现目标的正确方法是注册一个,并实现它以维持所需密钥的状态: 然后,您可以随时使用: 当然,您可以使用相同的方法来实现键映射及其包裹在状态中的状态。

  • 问题内容: 我正在尝试使用Carbon的功能为按下命令键时创建一个热键。我这样使用它: 但是,仅使用命令键时不会调用。如果我替换为其他任何非修饰键代码,则将调用处理程序。 有没有人有任何建议可以让应用程序在按下命令键时全局识别?谢谢。 问题答案: 您可以将与事件匹配的“全局事件监控器”添加到视图控制器,以便您可以检查它的modifierFlags与deviceIndependentFlagsMas

  • 问题内容: 我是Java的初学者,一直在研究如何检测用户是否按下了某个键(例如箭头键)。显然,有很多方法可以做到这一点,我发现此方法应该对我有用: 问题是我不知道什么是KeyEvent。 当我调用该方法并给我举个例子时,谁能告诉我在括号中加什么? PS:不要把我发送到其他站点,我可能已经看过了,他们只是让我更加困惑… 问题答案: public class KeyEvent extends Inpu

  • 问题内容: 我正在一个需要JavaScript和会话的页面上工作。我已经有代码来警告用户是否禁用了javascript。现在,我想处理禁用cookie的情况,因为会话ID存储在cookie中。 我只想到了几个主意: 将会话ID嵌入链接和表单中 警告用户如果禁用了cookie,则必须启用cookie(需要帮助来检测cookie是否被禁用) 解决此问题的最佳方法是什么?谢谢 编辑 根据链接的文章,我想