2012-02-01 211 views
5

我已经写了一个简单的Tkinter应用程序,在窗体底部有几个按钮。我的目标是按照在按钮上加下划线的标准惯例,并使用Alt键(即:“_S_ave”的Alt-s)绑定该字母的动作。将按钮绑定到Alt按键?

我试着将一个根窗口绑定到“Alt-s”,“Alt-KeyPress-s”和“Mod1-s”,并且没有一个可以可靠地工作。他们有时会开火,但即使我对事件功能有“返回休息”,“s”字母也会传播到输入窗口小部件。

我相信这是Linux/X11和Mod1与Alt处理的问题,因为控制键绑定工作一致。我一直无法找到任何解决此问题的最佳实践,因此我在此提出上诉。

有人可以分享如何获得在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的名单上找到了一个链接,可以帮助解释类似的行为,在https://bbs.archlinux.org/viewtopic.php?id=58145

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

谢谢。

+0

怎么样的一个片段,我们可以尝试在那里ALT不工作对于? – 2012-02-05 21:47:02

+0

我以为我会指出我正在使用平铺WM AwesomeWM,并有权修改xmodmap到其他东西,但左侧未经修改。 Emacs,Firefox,Openoffice和其他GUI应用程序通常会读取Alt键。 – Demosthenex 2012-02-06 03:51:49

+1

你的代码在python 2.7.1的windows XP下工作正常。对不起,我再也无法提供帮助了,我手边没有一台linux机器。 :/ 祝你好运。 – Symon 2012-02-06 20:23:21

回答

1

答案是修改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不会解释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 

什么乱七八糟的问题,通过间接的变化改变一个无证暗示的行为......

+0

另一个潜在的问题是,如果您正在使用Tk应用程序的对象,例如创建您自己的根类并从Tk继承,如果您未能调用父类__init__,则Tk可以工作,但没有任何绑定可以。在我的情况下,我设置了一个不正确的super()调用,只是一个友好的提醒。 – Demosthenex 2012-02-15 22:00:10

1

我不确定这是否会在Linux上以不同的方式工作,但我想我会给这个答案一枪,因为它已经几天没有回复。

我不知道如果这是你正在使用或没有语法,但不是return break尝试return ("break")

为中高音问题,也许你可以试试:

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. 

所以我真的不知道为什么休息不工作了你..对不起,我不能帮助更多。

+0

Alt-s似乎可靠地工作,但打破并不妨碍“s”进入入口小部件。我尝试了Python 2.6.6和3.2(只需稍作调整即可运行)。 – Demosthenex 2012-02-05 21:08:11

+0

@Symon:break不起作用的原因是,在绑定到根窗口或“全部”之前,小部件和小部件类上的绑定触发。因此,“休息”在周期中来得太晚。 – 2012-02-08 03:16:26

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) 
+0

我自己在Ubuntu 10.02上,并且用Python 2.6.6和3.2(用小的语法修复)尝试了它。它没有在Alt-f上触发。 – Demosthenex 2012-02-05 20:22:35

+0

在我的尝试中,只要根窗口被选中,它就会触发正常。我正在检查我的python/tkinter/tcl版本... – 2012-02-05 20:24:29

+0

我用马虎的焦点,但窗口被选中。当我使用Alt键触发菜单时,Firefox等其他GUI应用程序正常工作。 – Demosthenex 2012-02-05 21:10:34