I encountered an issue regarding KeyPress binds in tkinter when switching between Windows and Linux while using a NumPad. Using self.bind("-", function)
works on Windows, however is not triggered on Linux.
With the following code snippet I found out that the events of a keyboard-minus differs from a numpad-minus.
Code:
import tkinter as tk class App(tk.Tk): def __init__(self): tk.Tk.__init__(self) self.bind("<Key>", self.action) self.count = 0 def action(self, e): print(e) self.count += 1 app = App() app.mainloop()
Output:
NumPad: <KeyPress event state=Mod2 keysym=KP_Subtract keycode=82 char=‘-‘ x=323 y=-184 KeyBoard: <KeyPress event state=Mod2 Keysym=minus keycode=61 char=’-‘ x=376 y=-27
Is there a way to make Linux recognize the “-” char in a tkinter bind whether it is from keyboard or NumPad?
Advertisement
Answer
Is there a way to make Linux recognize the “-” char from both the keyboard and the NumPad in a tkinter bind?
I have wrote code where you can choose from the OptionMenu
from the options you have:
You could bind both keysyms to the same function. – jasonharper
keep binding to any key and dispatch based on the char attribute of the event. – Sven Marnach
use both the upper methods.
Running the provided code you can see that binding to both, ‘any key’ and the ‘minus’ key suppresses the key event for pressing ‘any key’ to be triggered in case the ‘minus’ key is pressed:
# https://stackoverflow.com/questions/63464407/cannot-bind-numpad-minus-key-on-linux-with-tkinter import tkinter as tk enable = None # enable = 'binding and action' # enable = 'binding only' # enable = 'only action' class App(tk.Tk): def __init__(self): global enable from tkinter import StringVar, OptionMenu tk.Tk.__init__(self) choices = ['binding and action', 'binding only', 'only action'] self.sv = StringVar() if enable == None: print("DEFAULT CHOICE: enable == 'binding and action'") enable = 'binding and action' if enable == 'binding and action': self.bind("<KP_Subtract>", self.on_minus_bind) self.bind("<minus>" , self.on_minus_bind) self.bind("<Key>", self.action) self.sv.set('binding and action') if enable == 'binding only': self.bind("<KP_Subtract>", self.on_minus_bind) self.bind("<minus>" , self.on_minus_bind) self.sv.set('binding only') if enable == 'only action': self.bind("<Key>", self.action) self.sv.set('only action') self.om = OptionMenu(None, self.sv, *choices, command=self.on_option_change) self.om.pack() self.count = 0 def on_option_change(self, e): enable = self.sv.get() if enable == 'binding and action': self.bind("<KP_Subtract>", self.on_minus_bind) self.bind("<minus>" , self.on_minus_bind) self.bind("<Key>", self.action) if enable == 'binding only': self.unbind("<Key>") self.bind("<KP_Subtract>", self.on_minus_bind) self.bind("<minus>" , self.on_minus_bind) if enable == 'only action': self.unbind("<KP_Subtract>") self.unbind("<minus>") self.bind("<Key>", self.action) def action(self, e): if e.char == '-': self.on_minus_action(e) else: print('action call: ', e, type(e)) self.count += 1 def on_minus_bind(self, e): print('bind-event : "minus" pressed', e, type(e)) def on_minus_action(self, e): print('action-call: "minus" pressed', e, type(e) ) app = App() app.mainloop()