为了账号安全,请及时绑定邮箱和手机立即绑定

Tkinter 自定义条目小部件异常

Tkinter 自定义条目小部件异常

慕哥6287543 2023-03-08 15:46:06
我正在尝试创建一个自定义 Tkinter Entry widget,它将在将字符插入小部件之前将小写字符转换为大写字符。我知道有一些解决方案可以将按键释放事件绑定到一个小部件,该小部件具有获取小部件文本然后转换为大写并重新插入文本的功能。但是这些解决方案在转换发生之前显示小写字符,我不想这样做。我正在尝试使用基于 Bryan Oakley 共享的代码的自定义 Entry 小部件 - Tkinter adding line number to text widget此代码非常适合自定义Text widget,我已在其他应用程序中使用过它。现在我正在尝试使用相同的方法来创建自定义 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 resultclass 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 resultdef get_text():    print("TEXT widget text = ", mytext.get("1.0", "end"))    print("ENTRY widget text = " ,entryvar.get())root = Tk()entryvar = StringVar()这些解决方案适用于CustomText小部件。如您所见,字符在插入之前进行了转换,结果就好像用户是在按下 shift 键的情况下输入字符一样。关于为什么会发生这种情况的任何想法?
查看完整描述

1 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

研究代码后,我发现在条目中插入文本后,index sel.first会调用该方法。但是没有选择,因此会出现错误“选择不在小部件中。!框架。!定制”。我不知道这是如何在常规中处理的Entry,但您可以捕获此错误:


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))

否则,您可以使用完全不同的方法来更改插入文本的大小写:对条目的文本变量使用跟踪。


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._var.trace_add('write', self._uppercase)该方法。_uppercase()StringVar


查看完整回答
反对 回复 2023-03-08
  • 1 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号