Tkinter 将按钮绑定到Alt按键?

Tkinter 将按钮绑定到Alt按键?,tkinter,Tkinter,我已经编写了一个简单的Tkinter应用程序,在表单底部有几个按钮。我的目标是遵循标准惯例,在按钮上为字母加下划线,并用Alt键绑定该字母的操作(即:Alt-s代表“\u s\u ave”) 我已经尝试将根窗口绑定到“Alt-s”、“Alt-KeyPress-s”和“Mod1-s”,但似乎没有一个能可靠地工作。它们有时会触发,但即使我的事件函数中有“return break”,也会将“s”字母传播到条目小部件 我认为这是Linux/X11和Mod1与Alt处理的一个问题,因为控件键绑定工作一致。

我已经编写了一个简单的Tkinter应用程序,在表单底部有几个按钮。我的目标是遵循标准惯例,在按钮上为字母加下划线,并用Alt键绑定该字母的操作(即:Alt-s代表“\u s\u ave”)

我已经尝试将根窗口绑定到“Alt-s”、“Alt-KeyPress-s”和“Mod1-s”,但似乎没有一个能可靠地工作。它们有时会触发,但即使我的事件函数中有“return break”,也会将“s”字母传播到条目小部件

我认为这是Linux/X11和Mod1与Alt处理的一个问题,因为控件键绑定工作一致。我还没有找到解决这个问题的最佳实践,因此我在这里很有吸引力

有人能分享一下如何让Alt键绑定在Linux/X11中工作吗

**更新了一个示例

from Tkinter import *

class GUI:
    def __init__(self,root):
        self.root = root
        e = Entry(self.root)
        e.grid(column=0,row=0)
        b = Button(self.root, text="Save", underline = 0)
        b.grid(column=0,row=1)
        root.bind("<Alt-s>",self.save)
        e.focus()

    def save(self,event=None):
        print("Hey, you pressed Alt-s!")
        return "break"

root = Tk()
App = GUI(root)
print("At this point, pressing Alt-s places the s string in the entry widget, and doesn't trigger")
root.mainloop()
从Tkinter导入*
类GUI:
定义初始化(自,根):
self.root=根
e=条目(self.root)
e、 网格(列=0,行=0)
b=按钮(self.root,text=“保存”,下划线=0)
b、 网格(列=0,行=1)
root.bind(“”)

我已经对我的xmodmap做了更改,现在Alt按预期工作。我无法解释为什么将Alt_R绑定到mod4会影响Alt_L,或者为什么它只会影响Tk应用程序


谢谢。

我不确定这在linux上是否会有不同的效果,但我想我会尝试一下这个答案,因为已经有几天没有回复了

我不确定这是否是您正在使用的语法,但请尝试使用
return-break
try
return(“break”)

至于alt问题,可以尝试以下方法:

from Tkinter import *

class GUI:
    def __init__(self,root):    
        self.alt = False
        e = Entry(root)
        e.pack()
        e.focus()
        root.bind("<Alt_L>",self.AltOn)
        root.bind("<KeyRelease-Alt_L>",self.AltOff)
        root.bind("<s>",self._s)

    def AltOn(self,event): self.alt=True
    def AltOff(self,event): self.alt=False
    def _s(self,event):
        if self.alt:
            #whatever you want to do with alt+s
            print "ALT S"
            return ("break")

root = Tk()
App = GUI(root)
root.mainloop()
所以我真的不知道为什么break对你不起作用。对不起,我帮不了你更多。

修改后的答案:

通过向条目添加第二个绑定(Ubuntu 10.04),我可以让您的示例正常工作,而不是填充条目框:


答案是修改Alt_R以将其绑定到Windows键(Mod4)是问题的根本原因。我相信这使Alt_L可以作为Mod1工作,尽管它在xmodmap中没有被显式修改。因此它一定破坏了一些隐含的行为,但仅适用于Tk应用程序

从Arch BBS链接修改Alt_R键代码以触发Super_L解决了该行为。因此,现在Alt_R作为Windows键起作用,但Tk没有注意到Alt_L的任何更改

Alt的根绑定现在可以在没有双重绑定的情况下正常工作,因为条目小部件默认情况下会忽略Alt键按下。通过正确的Alt行为,不仅Alt键绑定可以正常工作,而且不需要返回中断行为

我没有在任何小部件中看到Mod1键的默认忽略绑定,如果Alt_L突然决定提供Mod1,这确实解释了Mod1绑定将触发的行为,但是需要双重绑定来防止Entry小部件获取键

~/.Xmodmap供参考:

! ISO_Level3_Shift is what xev reports for my right Alt key
! mod4 is the Windows key modifier, and tied to WM operations

! Trying a different approach documented at
! https://bbs.archlinux.org/viewtopic.php?id=58145
keycode 108 = Super_L
remove mod1 = Super_L

这是一个多么混乱的问题,通过一个间接的改变来改变一个未记录的隐含行为…

我自己也在Ubuntu 10.02上,并在Python 2.6.6和3.2上进行了尝试(有一些小的语法修正)。它没有在Alt-f上触发。在我的尝试中,只要选择了根窗口,它就会触发。我正在检查我的python/tkinter/tcl版本…我使用了草率的焦点,但窗口被选中。当我用Alt键触发菜单时,其他GUI应用程序(如Firefox)工作正常。我检查了,我在Ubuntu中的2.6.6安装与您的一致。他发现了问题是的,我一直无法找出alt键不起作用的原因。您的示例很好…这与我尝试的类似。@Demostenex:您必须绑定两次,因为根窗口上的绑定是在默认条目小部件绑定之后触发的。因此,返回“break”来得太迟,因为已插入字符。有关绑定标记的详细信息,请阅读。顺便说一句,有其他方法可以解决此问题,但不必绑定两次,但这需要更改所有小部件的绑定标记,这通常比实际情况更麻烦。Alt-s似乎工作可靠,但break无法阻止“s”我尝试了Python 2.6.6和3.2(进行了一些小的调整,使其能够运行)。@Symon:break不起作用的原因是小部件和小部件类上的绑定在绑定到根窗口或“all”之前触发。因此,“break”在这个循环中来的太晚了。我们可以在alt不适用的地方尝试一个片段怎么样?我想我应该指出我使用的是平铺WM AwesomeWM,并且右mod xmodmapping到了其他东西,但左mod xmodmapping没有修改。Emacs、Firefox、Openoffice和其他GUI应用程序通常读取alt键。你的代码在windows XP中使用p时可以正常工作ython 2.7.1.很抱歉,我不能再帮你了,我手头没有linux机器。:/good luck.我感谢你迄今为止的帮助。正如我所说,我相信这与linux处理Alt/mod有关。我不确定你为什么被否决,+1用于简明的问题描述和更新。另一个潜在问题是,如果你正在为Tk应用程序使用对象,例如我nstance创建自己的根类并从Tk继承如果无法调用父类init,Tk可以工作,但所有绑定都不能。在我的例子中,我设置了一个错误的super()调用,只是一个友好的提醒。
e.bind("<Alt-s>",self.save)
e.bind("<Option-s>",self.save)
xmodmap:  up to 4 keys per modifier, (keycodes in parentheses):    
shift       Shift_L (0x32),  Shift_R (0x3e)
lock        Caps_Lock (0x42)
control     Control_L (0x25),  Control_R (0x69)
mod1        Alt_L (0x40),  Alt_R (0x6c),  Meta_L (0xcd)
mod2        Num_Lock (0x4d)
mod3      
mod4        Super_L (0x85),  Super_R (0x86),  Super_L (0xce),  Hyper_L (0xcf)
mod5        ISO_Level3_Shift (0x5c),  Mode_switch (0xcb)
! ISO_Level3_Shift is what xev reports for my right Alt key
! mod4 is the Windows key modifier, and tied to WM operations

! Trying a different approach documented at
! https://bbs.archlinux.org/viewtopic.php?id=58145
keycode 108 = Super_L
remove mod1 = Super_L