Привязка кнопок к нажатию клавиш Alt? - PullRequest
5 голосов
/ 01 февраля 2012

У меня есть простое приложение Tkinter, которое я написал, с несколькими кнопками внизу формы.Моя цель - следовать стандартному соглашению, заключающемуся в подчеркивании буквы на кнопке и связывании действия для этой буквы клавишей Alt (т. Е. Alt-s для «_S_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()

** Обновление 2

У меня было несколько рецензентов, дающих мне знать, что это работает в их системе, даже в Linux.Возможно, есть проблема с моим tiling wm или другой конфигурацией для X11, однако у меня не было проблем с использованием Alt с любыми другими приложениями X11 с графическим интерфейсом.

Я открыт для предложений по устранению неполадок.

** Обновление 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.

Спасибо.

Ответы [ 3 ]

1 голос
/ 05 февраля 2012

Исправленный ответ:

Я смог заставить ваш пример работать и не заполнять поле ввода, добавив в него вторую привязку (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)
1 голос
/ 11 февраля 2012

Ответ заключается в том, что основной причиной проблемы была модификация 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

Какая грязная проблема, изменяющая недокументированное подразумеваемое поведение посредством косвенного изменения ...

1 голос
/ 04 февраля 2012

Я не уверен, что это будет работать по-другому на 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.

Так что я действительно не уверен, почему перерыв не работает для вас .. извините, я не могу помочь больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...