Python tkinter (copy/paste not working with other languages)
Question:
I found out that whenever i switch the language from english to russian tkinter stops reacting to Ctrl+C, Ctrl+V or Ctrl+X.
It still works when i switch back to english, even if the text is in russian.
I tried all code snippets i could find on stack exchange remotely related to copy-paste topic, adding stuff similar to original code like self.bind('<Control-м>', self.paste)
(“м” is the same button in russian as “v” in english), but still nothing works.
Would really appreciate any help/ideas on how to fix it.
Answers:
You can use <Key>
to check what keycode
is used when you press Control-м
and then use it to find keysym
on page like Tcl/Tk – keysym. Maybe you will have to use <Control-Cyrillic_em>
import tkinter as tk
def copy(event):
print('copy')
def paste(event):
print('paste')
def test(event):
print('event.char:', event.char)
print('event.keycode:', event.keycode)
print('event.keysym:', event.keysym)
print('---')
root = tk.Tk()
root.bind('<Key>', test)
root.bind('<Control-c>', copy)
root.bind('<Control-v>', paste)
root.bind('<Control-Cyrillic_em>', paste)
root.mainloop()
from Tkinter import Tk, Entry
def _onKeyRelease(event):
ctrl = (event.state & 0x4) != 0
if event.keycode==88 and ctrl and event.keysym.lower() != "x":
event.widget.event_generate("<<Cut>>")
if event.keycode==86 and ctrl and event.keysym.lower() != "v":
event.widget.event_generate("<<Paste>>")
if event.keycode==67 and ctrl and event.keysym.lower() != "c":
event.widget.event_generate("<<Copy>>")
master = Tk()
master.geometry("500x500+1+1")
master.bind_all("<Key>", _onKeyRelease, "+")
Entry(master).pack()
Entry(master).pack()
Entry(master).pack()
master.mainloop()
I did this.
1.First received the current layout language on the advice of here:
def is_ru_lang_keyboard(self):
u = ctypes.windll.LoadLibrary("user32.dll")
pf = getattr(u, "GetKeyboardLayout")
return hex(pf(0)) == '0x4190419'
2. Then I defined the keys() method taking into account the layout, because without a condition in the case of the English layout, the method gave a duplicate string when inserting:
def keys(event):
if self.is_ru_lang_keyboard():
if event.keycode==86:
event.widget.event_generate("<<Paste>>")
if event.keycode==67:
event.widget.event_generate("<<Copy>>")
if event.keycode==88:
event.widget.event_generate("<<Cut>>")
if event.keycode==65535:
event.widget.event_generate("<<Clear>>")
if event.keycode==65:
event.widget.event_generate("<<SelectAll>>")
3.Bound the keys() method of the Entry field to the "Control-KeyPress" event:
self.my_entry.bind("<Control-KeyPress>", keys)
I found out that whenever i switch the language from english to russian tkinter stops reacting to Ctrl+C, Ctrl+V or Ctrl+X.
It still works when i switch back to english, even if the text is in russian.
I tried all code snippets i could find on stack exchange remotely related to copy-paste topic, adding stuff similar to original code like self.bind('<Control-м>', self.paste)
(“м” is the same button in russian as “v” in english), but still nothing works.
Would really appreciate any help/ideas on how to fix it.
You can use <Key>
to check what keycode
is used when you press Control-м
and then use it to find keysym
on page like Tcl/Tk – keysym. Maybe you will have to use <Control-Cyrillic_em>
import tkinter as tk
def copy(event):
print('copy')
def paste(event):
print('paste')
def test(event):
print('event.char:', event.char)
print('event.keycode:', event.keycode)
print('event.keysym:', event.keysym)
print('---')
root = tk.Tk()
root.bind('<Key>', test)
root.bind('<Control-c>', copy)
root.bind('<Control-v>', paste)
root.bind('<Control-Cyrillic_em>', paste)
root.mainloop()
from Tkinter import Tk, Entry
def _onKeyRelease(event):
ctrl = (event.state & 0x4) != 0
if event.keycode==88 and ctrl and event.keysym.lower() != "x":
event.widget.event_generate("<<Cut>>")
if event.keycode==86 and ctrl and event.keysym.lower() != "v":
event.widget.event_generate("<<Paste>>")
if event.keycode==67 and ctrl and event.keysym.lower() != "c":
event.widget.event_generate("<<Copy>>")
master = Tk()
master.geometry("500x500+1+1")
master.bind_all("<Key>", _onKeyRelease, "+")
Entry(master).pack()
Entry(master).pack()
Entry(master).pack()
master.mainloop()
I did this.
1.First received the current layout language on the advice of here:
def is_ru_lang_keyboard(self):
u = ctypes.windll.LoadLibrary("user32.dll")
pf = getattr(u, "GetKeyboardLayout")
return hex(pf(0)) == '0x4190419'
2. Then I defined the keys() method taking into account the layout, because without a condition in the case of the English layout, the method gave a duplicate string when inserting:
def keys(event):
if self.is_ru_lang_keyboard():
if event.keycode==86:
event.widget.event_generate("<<Paste>>")
if event.keycode==67:
event.widget.event_generate("<<Copy>>")
if event.keycode==88:
event.widget.event_generate("<<Cut>>")
if event.keycode==65535:
event.widget.event_generate("<<Clear>>")
if event.keycode==65:
event.widget.event_generate("<<SelectAll>>")
3.Bound the keys() method of the Entry field to the "Control-KeyPress" event:
self.my_entry.bind("<Control-KeyPress>", keys)