Python Tkinter自定义条目小部件异常
我正在尝试创建一个自定义TkinterPython Tkinter自定义条目小部件异常,python,tkinter,widget,Python,Tkinter,Widget,我正在尝试创建一个自定义Tkinter条目小部件,它将在将字符插入小部件之前将小写字符转换为大写字符。我知道有一些解决方案可以将密钥释放事件绑定到一个小部件,并使用一个函数获取小部件文本,然后转换为大写并重新插入文本。但是这些解决方案在转换发生之前显示小写字符,我不希望这样做 我正在尝试使用一个基于Bryan Oakley共享代码的自定义条目小部件- 这段代码适用于定制的文本小部件,我在其他应用程序中也使用过它 现在,我尝试使用相同的方法来创建自定义条目小部件。下面是包含自定义文本小部件和自定义
条目小部件
,它将在将字符插入小部件之前将小写字符转换为大写字符。我知道有一些解决方案可以将密钥释放事件绑定到一个小部件,并使用一个函数获取小部件文本,然后转换为大写并重新插入文本。但是这些解决方案在转换发生之前显示小写字符,我不希望这样做
我正在尝试使用一个基于Bryan Oakley共享代码的自定义条目小部件-
这段代码适用于定制的文本小部件
,我在其他应用程序中也使用过它
现在,我尝试使用相同的方法来创建自定义条目小部件。下面是包含自定义文本小部件和自定义输入小部件的示例代码:
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)
中得到以下异常:
回溯(最近一次呼叫最后一次):
文件“C:/Users/rhkea/AppData/Roaming/JetBrains/PyCharmCE2020.1/scratches/custom_entry_box.py”,第57行,在
root.mainloop()
文件“C:\Users\rhkea\AppData\Local\Programs\Python\Python37\lib\tkinter\\uuuuu init\uuuuu.py”,第1283行,在mainloop中
self.tk.mainloop(n)
文件“C:/Users/rhkea/AppData/Roaming/JetBrains/PyCharmCE2020.1/scratches/custom_entry_box.py”,第34行,在代理中
结果=self.tk.call(cmd)
_tkinter.TclError:选择不在小部件中。!框架海关条目
你知道为什么会发生这种情况吗?在仔细研究代码之后,我发现在条目中插入文本后,会调用方法
index sel.first
。但没有选择,因此引发错误“选择不在小部件中。!frame。!customentry”。我不知道在常规的条目中如何处理此问题,但您可以捕获此错误:
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
try:
return self.tk.call(cmd)
except TclError as e:
if args[0] == 'index' and args[1] == 'sel.first':
pass
else:
raise TclError(str(e))
否则,您可以使用完全不同的方法来更改插入文本的大小写:对条目的textvariable使用跟踪
class CustomEntry(Entry):
def __init__(self, *args, **kwargs):
Entry.__init__(self, *args, **kwargs)
self._var = StringVar(self)
self.configure(textvariable=self._var)
self._var.trace_add('write', self._uppercase)
def _uppercase(self, *args):
self._var.set(self._var.get().upper())
使用self.\u var.trace\u add('write',self.\u大写)
,每次StringVar
的内容更改时都会调用方法\u uppercase()
。在处理代码之后,我发现在条目中插入文本后,会调用方法index sel.first
。但没有选择,因此引发错误“选择不在小部件中。!frame。!customentry”。我不知道在常规的条目中如何处理此问题,但您可以捕获此错误:
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
try:
return self.tk.call(cmd)
except TclError as e:
if args[0] == 'index' and args[1] == 'sel.first':
pass
else:
raise TclError(str(e))
否则,您可以使用完全不同的方法来更改插入文本的大小写:对条目的textvariable使用跟踪
class CustomEntry(Entry):
def __init__(self, *args, **kwargs):
Entry.__init__(self, *args, **kwargs)
self._var = StringVar(self)
self.configure(textvariable=self._var)
self._var.trace_add('write', self._uppercase)
def _uppercase(self, *args):
self._var.set(self._var.get().upper())
使用self.\u var.trace\u add('write',self.\u大写)
,每次StringVar
的内容更改时都会调用方法\u uppercase()。它们不可搜索,视力受损者根本无法阅读。确定-更改为将异常显示为文本。最好包含整个stacktrace。请不要发布stacktraces的图片。它们是不可搜索的,视力受损者根本无法阅读它们。Ok-更改为将异常显示为文本。最好包含整个堆栈跟踪。