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

时间:2016-02-09 22:07:20

标签: tkinter

如何在同一个Tkinter文本小部件中同时使用line numberread only个代理?我可以看到两者,但其中一个或另一个都可以。我假设问题在下面的代码片段中对于两者都是相同的:

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

以下仅使只读部分有效,切换顺序使自定义文本有效。

    class TextOfBryan(ReadOnly, CustomText):
          pass

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

1 个答案:

答案 0 :(得分:1)

您需要将两个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
    }

    ''')