11"""
22Keybinding system for customtkinter
3-
43Provides layout-independent keyboard keybind registration that works across
54platforms and keyboard layouts by physical keycode logic.
65
1514 from .keybinding import unregister_keybind
1615 unregister_keybind(root, "CmdOrCtrl+P") # remove all callbacks for this keybind on target
1716 unregister_keybind(entry, "Ctrl+Return", on_submit) # remove specific callback
18-
1917Notes:
2018 - You can pass either a toplevel/root (tk.Tk, tk.Toplevel, CTk, CTkToplevel)
2119 or ANY Tk/CustomTkinter widget (e.g., CTkTextbox, CTkEntry).
@@ -68,7 +66,6 @@ def _get_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
6866
6967def _build_platform_keymaps () -> Tuple [Dict [str , int ], Dict [str , int ]]:
7068 """Return (function_keys, special_keys) dicts for the current platform.
71-
7269 This centralizes platform keycodes to avoid duplication.
7370 """
7471 if sys .platform == 'win32' :
@@ -90,10 +87,10 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
9087 'ESCAPE' : 27 , 'ESC' : 27 ,
9188 'SPACE' : 32 ,
9289 'BACKSPACE' : 8 ,
93- 'PLUS' : 187 , 'EQUAL' : 187 , '=' : 187 , # Main keyboard =/+ key
94- 'NUMPAD_PLUS' : 107 , 'NUMPAD_ADD' : 107 , # Numpad +
95- 'MINUS' : 189 , 'HYPHEN' : 189 , '-' : 189 , # Main keyboard -/_ key
96- 'NUMPAD_MINUS' : 109 , 'NUMPAD_SUBTRACT' : 109 , # Numpad -
90+ 'PLUS' : 187 , 'EQUAL' : 187 , '=' : 187 ,
91+ 'NUMPAD_PLUS' : 107 , 'NUMPAD_ADD' : 107 ,
92+ 'MINUS' : 189 , 'HYPHEN' : 189 , '-' : 189 ,
93+ 'NUMPAD_MINUS' : 109 , 'NUMPAD_SUBTRACT' : 109 ,
9794 'COMMA' : 188 , ',' : 188 ,
9895 'PERIOD' : 190 , '.' : 190
9996 }
@@ -106,7 +103,7 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
106103 }
107104 special_keys = {
108105 'DELETE' : 117 , 'DEL' : 117 , # Forward Delete (both unified)
109- 'BACKSPACE' : 51 , # Backspace key
106+ 'BACKSPACE' : 51 ,
110107 'INSERT' : 114 ,
111108 'HOME' : 115 , 'END' : 119 ,
112109 'PAGE_UP' : 116 , 'PAGEUP' : 116 , 'PGUP' : 116 ,
@@ -116,10 +113,10 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
116113 'ENTER' : 36 , 'RETURN' : 76 , # keypad Enter = 76
117114 'ESCAPE' : 53 , 'ESC' : 53 ,
118115 'SPACE' : 49 ,
119- 'PLUS' : 69 , 'EQUAL' : 69 , '=' : 69 , # Main keyboard =/+ key
120- 'NUMPAD_PLUS' : 78 , 'NUMPAD_ADD' : 78 , # Numpad +
121- 'MINUS' : 27 , 'HYPHEN' : 27 , '-' : 27 , # Main keyboard -/_ key
122- 'NUMPAD_MINUS' : 75 , 'NUMPAD_SUBTRACT' : 75 , # Numpad -
116+ 'PLUS' : 69 , 'EQUAL' : 69 , '=' : 69 ,
117+ 'NUMPAD_PLUS' : 78 , 'NUMPAD_ADD' : 78 ,
118+ 'MINUS' : 27 , 'HYPHEN' : 27 , '-' : 27 ,
119+ 'NUMPAD_MINUS' : 75 , 'NUMPAD_SUBTRACT' : 75 ,
123120 'COMMA' : 43 , ',' : 43 ,
124121 'PERIOD' : 47 , '.' : 47
125122 }
@@ -142,10 +139,10 @@ def _build_platform_keymaps() -> Tuple[Dict[str, int], Dict[str, int]]:
142139 'ESCAPE' : 9 , 'ESC' : 9 ,
143140 'SPACE' : 65 ,
144141 'BACKSPACE' : 22 ,
145- 'PLUS' : 21 , 'EQUAL' : 21 , '=' : 21 , # Main keyboard =/+ key
146- 'NUMPAD_PLUS' : 86 , 'NUMPAD_ADD' : 86 , # Numpad +
147- 'MINUS' : 20 , 'HYPHEN' : 20 , '-' : 20 , # Main keyboard -/_ key
148- 'NUMPAD_MINUS' : 82 , 'NUMPAD_SUBTRACT' : 82 , # Numpad -
142+ 'PLUS' : 21 , 'EQUAL' : 21 , '=' : 21 ,
143+ 'NUMPAD_PLUS' : 86 , 'NUMPAD_ADD' : 86 ,
144+ 'MINUS' : 20 , 'HYPHEN' : 20 , '-' : 20 ,
145+ 'NUMPAD_MINUS' : 82 , 'NUMPAD_SUBTRACT' : 82 ,
149146 'COMMA' : 59 , ',' : 59 ,
150147 'PERIOD' : 60 , '.' : 60
151148 }
@@ -179,7 +176,6 @@ def _get_group_id(widget: Any) -> int:
179176
180177def _parse_modifiers (mod_tokens : List [str ]) -> Tuple [str , List [str ]]:
181178 """Normalize a list of modifier tokens into a canonical key and Tk names.
182-
183179 Returns:
184180 mods_key: canonical string like 'ctrl', 'ctrl+shift', or 'none'
185181 tk_mods: list of Tk modifier names like ['Control', 'Shift']
@@ -222,11 +218,9 @@ def _parse_modifiers(mod_tokens: List[str]) -> Tuple[str, List[str]]:
222218
223219def register_keybind (widget_or_root : Any , keybind : str , callback : Callable , * , bind_scope : str = 'window' ) -> None :
224220 """Register a keyboard keybind that works regardless of keyboard layout.
225-
226221 Supported Modifiers: Ctrl, Alt, Shift, Cmd (macOS)
227222 Supported Keys: A-Z, 0-9, F1-F12, Delete, Insert, Home, End, Page_Up, Page_Down, etc.
228223 Supports both single keys (F1, F2, Delete) and modified keys (Ctrl+S, Alt+F4)
229-
230224 Args:
231225 widget_or_root: Any Tk/CustomTkinter widget or a toplevel/root.
232226 keybind: Keybind string in format 'Modifier+Key' or just 'Key' (e.g., "Ctrl+S", "Alt+F4", "F1")
@@ -402,13 +396,11 @@ def _on_destroy(event, t_id=target_id, tgt=target):
402396
403397def unregister_keybind (widget_or_root : Any , keybind : str , callback : Callable | None = None , * , bind_scope : str = 'window' ) -> bool :
404398 """Unregister keybind from a window or a specific widget.
405-
406399 Args:
407400 widget_or_root: Any Tk/CustomTkinter widget or a toplevel/root.
408401 keybind: Keybind string 'Modifier+Key' or just 'Key'. Supports 'CmdOrCtrl'.
409402 callback: Optional specific callback to remove. If None, removes all callbacks for this keybind.
410403 bind_scope: 'window' to target the widget's toplevel, or 'widget' to target only the widget.
411-
412404 Returns:
413405 True if something was removed, False otherwise.
414406 """
0 commit comments