Я пытаюсь создать собственный Tkinter Entry widget
, который преобразует символы нижнего регистра в верхний регистр до того, как символы будут вставлены в виджет. Я знаю, что есть решения, которые привязывают события отпускания клавиш к виджету с функцией получения текста виджета, а затем конвертируют его в верхний регистр и повторно вставляют текст. Но в этих решениях перед преобразованием отображается символ нижнего регистра, чего я предпочитаю не делать. в текстовый виджет
Этот код отлично подходит для пользовательского Text widget
, и я использовал его в других приложениях.
Теперь я пытаюсь использовать тот же подход для создания пользовательский виджет Entry. Вот пример кода, который включает как настраиваемый виджет Text, так и настраиваемый виджет Entry:
from tkinter import *
class CustomText(Text):
def __init__(self, *args, **kwargs):
Text.__init__(self, *args, **kwargs)
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
def _proxy(self, *args):
if args[0] == "insert" and args[1] == "insert":
args =('insert', 'insert', args[2].upper())
cmd = (self._orig,) + args
result = self.tk.call(cmd)
return result
class CustomEntry(Entry):
def __init__(self, *args, **kwargs):
Entry.__init__(self, *args, **kwargs)
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
def _proxy(self, *args):
if args[0] == "insert" and args[1] == "insert":
args =('insert', 'insert', args[2].upper())
cmd = (self._orig,) + args
result = self.tk.call(cmd)
return result
def get_text():
print("TEXT widget text = ", mytext.get("1.0", "end"))
print("ENTRY widget text = " ,entryvar.get())
root = Tk()
entryvar = StringVar()
root.geometry("300x300")
myframe = Frame(root, width = 300, height = 300)
Label(myframe, text="TEXT WIDGET").pack(side = TOP)
myframe.pack(side = TOP)
mytext = CustomText(myframe, width = 30, height=1, wrap="none")
mytext.pack(side = TOP)
Label(myframe, text="ENTRY WIDGET").pack(side = TOP)
myentry = CustomEntry(myframe, textvariable=entryvar, width = 30)
myentry.pack(side = TOP)
Button(myframe, text="Get Entry Widget Text", command=get_text).pack(side=TOP)
root.mainloop()
Решения работают для виджета CustomText
. Как видите, символы преобразуются перед вставкой, и в результате пользователь вводит символы с нажатой клавишей Shift.
Но я получаю исключение при вводе данных в виджет CustomEntry
, который я получаю следующее исключение из result = self.tk.call(cmd)
:
Traceback (most recent call last):
File "C:/Users/rhkea/AppData/Roaming/JetBrains/PyCharmCE2020.1/scratches/custom_entry_box.py", line 57, in <module>
root.mainloop()
File "C:\Users\rhkea\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1283, in mainloop
self.tk.mainloop(n)
File "C:/Users/rhkea/AppData/Roaming/JetBrains/PyCharmCE2020.1/scratches/custom_entry_box.py", line 34, in _proxy
result = self.tk.call(cmd)
_tkinter.TclError: selection isn't in widget .!frame.!customentry
Есть идеи, почему это может происходить?