2012-02-01 209 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