在Tcl Tk中删除插入后带有现有值的条目中的自动完成功能

时间:2017-09-22 21:33:32

标签: tcl tk

我使用tcl tk wiki中现有代码的帮助来在条目小部件中实现自动完成功能。 http://wiki.tcl.tk/13267(以下引用的相关部分):

proc autocomplete {win action validation value valuelist} {
   if {$action == 1 & $value != {} & [set pop [lsearch -inline $valuelist $value*]] != {}} {
     $win delete 0 end;  $win insert end $pop
     $win selection range [string length $value] end
     $win icursor [string length $value]
   } else {
     $win selection clear
   }
   after idle [list $win configure -validate $validation]
   return 1
 }
     

应用于这样的条目:

entry .test -validate all -validatecommand {autocomplete %W %d %v %P $fruitlist}

现在,如果我的数据列表包含以下数据:

test of result
test again
rule and result

我输入“te”或“t”我会在条目中自动收到“test again”建议。但是,当我从'te'删除e时,除非我输入另一封信,否则当我只输入't'时,我不会再收到更多的建议。

在删除某些字母后,有没有办法让自动填充功能继续存在于条目中?

1 个答案:

答案 0 :(得分:0)

自动完成代码仅在插入后执行重要操作,因为它会检查回调中的操作以查看它是否为1,这表示插入。您需要扩展代码,以便在操作为0时(即删除后)执行某些操作。不幸的是,当您尝试执行此操作时,最简单的扩展有点错误,因为当您删除刚刚插入的自动完成文本时,回调会立即为您恢复!最基本的解决方法是检查实际删除的文本是否只有一个字符;如果没有,它可能是删除选择,不应该触发完成。

这是我的更新版本。它还包括对Wiki页面上注明的错误的修复,其中包含单词列表中的全局特殊字符。

proc autocomplete {win action validation delta value valuelist} {
    after idle [list $win configure -validate $validation]
    if {$value ne "" && ($action == 1 || ($action == 0 && [string length $delta] == 1))} {
        set pattern [string map {\\ \\\\ \[ \\\[ \] \\\] * \\* ? \\?} $value]*
        set pop [lsearch -inline $valuelist $pattern]
        if {$pop ne {}} {
            $win delete 0 end
            $win insert end $pop
            $win selection range [string length $value] end
            $win icursor [string length $value]
            return 1
        }
    }
    $win selection clear
    return 1
}

添加了一个额外的参数(delta),以支持确定删除了多少文本,这需要绑定到验证回调脚本中的%S替换,例如,如下所示: / p>

entry .test -validate all -validatecommand {autocomplete %W %d %v %S %P $fruitlist}

更自动完成的更正确的修复方法是维护状态模型,以确定是否通过自动完成与前一个操作插入正在删除的文本,或者是否通过不同的用户操作完成,因此允许在删除时禁用自动完成仅当它是被删除的自动填充文本时。但那真的很复杂。