将按钮绑定到Alt按键?

时间:2012-02-01 13:08:41

标签: tkinter

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

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

我认为这是Linux / X11和Mod1与Alt处理的问题,因为Control键绑定工作一致。我无法找到解决问题的最佳做法,因此我在这里有吸引力。

有人可以分享如何在Linux / X11中使用Alt键绑定吗?

**更新样本

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()

**更新2

我有一些评论家让我知道这可以在他们的系统上运行,甚至是Linux。我的平铺wm或X11的其他配置可能存在问题,但是我在使用Alt与任何其他X11 GUI应用程序时没有任何问题。

我愿意接受有关如何解决此问题的建议。

**更新3

我一直在审查xmodmap的行为,看来当我分配Alt_R时,Tk键绑定会停止工作。 xev报告的事件与逐字匹配,但Tk的行为发生了变化。还在挖掘。

**更新4

先生。 Tkinter列表中的Lange在https://bbs.archlinux.org/viewtopic.php?id=58145找到了一个有助于解释类似行为的链接。

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

感谢。

3 个答案:

答案 0 :(得分:1)

我不确定这在linux上是否会有所不同,但我想我会给出这个答案,因为它已经过了几天没有回复。

我不确定这是否是您正在使用的语法,而不是return break尝试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()

编辑:绑定的描述是:

    FUNC will be called if the event sequence occurs with an
    instance of Event as argument. If the return value of FUNC is
    "break" no further bound function is invoked.

所以我真的不确定为什么休息不适合你..对不起我帮不了多。

答案 1 :(得分:1)

修改回答:

我能够让你的例子工作,而不是通过在条目中添加第二个绑定来填充输入框(Ubuntu 10.04):

e.bind("<Alt-s>",self.save)

在OSX Lion系统(相同的键盘)上:

e.bind("<Option-s>",self.save)

xmodmap(Ubuntu 10.04):

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)

答案 2 :(得分:1)

答案是修改Alt_R以将其绑定到Windows密钥(Mod4)是问题的根本原因。我相信使Alt_L作为Mod1工作,虽然它在xmodmap中明确没有被修改。因此,它必须打破一些隐含的行为,但仅限于Tk应用程序。

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

Alt的Root绑定现在可以正常工作而不需要双重绑定,因为Entry小部件默认忽略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

这是一个多么棘手的问题,通过间接改变来改变无证的隐含行为......