Tkinter 文本中的行号和只读小部件代理



如何在同一个 Tkinter 文本小部件中同时使用行号和只读代理?我可以让两者都可见,但其中一个或另一个有效。我假设问题出在下面的代码片段中,两者相同:

     self.tk.eval('''
        rename {widget} _{widget}
        interp alias {{}} ::{widget} {{}} widget_proxy _{widget} 
    '''.format(widget=str(self)))

下面使只读部分仅工作,切换顺序使自定义文本工作。

    class TextOfBryan(ReadOnly, CustomText):
          pass

当我将两个类的内容复制/粘贴到一个类中时,我收到一个错误,指出名称".xxxx.xxxx"已经存在并且无法重命名。

您需要

将两个widget_proxy定义合并为一个。它看起来像这样:

self.tk.eval('''
    proc widget_proxy {actual_widget widget_command args} {
        set command [lindex $args 0]
        if {$command == "insert"} {
            set index [lindex $args 0]
            if [_is_readonly $actual_widget $index "$index+1c"] {
                bell
                return ""
            }
        }
        if {$command == "delete"} {
            foreach {index1 index2} [lrange $args 1 end] {
                if {[_is_readonly $actual_widget $index1 $index2]} {
                    bell
                    return ""
                }
            }
        }
        # call the real tk widget command with the real args
        set result [uplevel [linsert $args 0 $widget_command]]
        # generate the event for certain types of commands
        if {([lindex $args 0] in {insert replace delete}) ||
            ([lrange $args 0 2] == {mark set insert}) || 
            ([lrange $args 0 1] == {xview moveto}) ||
            ([lrange $args 0 1] == {xview scroll}) ||
            ([lrange $args 0 1] == {yview moveto}) ||
            ([lrange $args 0 1] == {yview scroll})} {
            event generate  $actual_widget <<Change>> -when tail
        }
        # return the result from the real widget command
        return $result
    }
    proc _is_readonly {widget index1 index2} {
        # return true if any text in the range between
        # index1 and index2 has the tag "readonly"
        set result false
        if {$index2 eq ""} {set index2 "$index1+1c"}
        # see if "readonly" is applied to any character in the
        # range. There's probably a more efficient way to do this, but
        # this is Good Enough
        for {set index $index1} 
            {[$widget compare $index < $index2]} 
            {set index [$widget index "$index+1c"]} {
                if {"readonly" in [$widget tag names $index]} {
                    set result true
                    break
                }
            }
        return $result
    }
    ''')

最新更新