如果用过
Python
的
idle
或者之类的文本型命令行编辑器,你就会发现使用这类工具的可以随意复制黏贴的好处,这比传统的命令行工具方便了很多。但是,传统的优势在于,已执行的命令及得到的返回结果是只读的,不必担心因为误操作破坏历史记录,而这点在
Tk
的
text
组件很难实现。就是说,
text
天然并不支持在一个文本框对象中实现部分只读,而另一部分可写的状态。
text
的
state
选项只能是整个对象处于只读或者可写的状体。那么像
idle
这样的工具是怎么实现局部只读的呢?特别是
idle
本身即是用
Tk
写成的。最初我认为这可能是使用了
canvas
组件里实现类
text
功能,但之后我还是使用了
rename
办法在
text
的
insert
和
delete
命令前注入代码,从而实现这一功能。
1.proc init_region_readonly {text} {
2. rename $text fake
3. proc $text {args} {
4. switch [lindex $args 0] {
5. "insert" {
6. if [fake compare insert >= $::com_region_readonly] {
7. uplevel 1 fake $args
8. }
9. }
10. "delete" {
11. if [fake compare insert > $::com_region_readonly] {
12. uplevel 1 fake $args
13. }
14. }
15. "default" {
16. uplevel 1 fake $args
17. }
18. }
19. }
20.}
在第
6
行和第
11
行里,我增加了对于输入点的判断,也就是说只有当输入点的
index
处于以一个名为
com_region_readonly
的全局变量所指定的位置后时,输入才是有效的,否则将丢弃本次操作。这被应用于
cucumber1.1.1
中所集成的
tclsh
命令行工具中,当然这个工具实现的不仅仅模拟
tclsh
,还有类似于
vim
的文本操作命令,这是基于几个
alias
给子解析器的命令实现的,以后再作介绍。