Tk中监控多个按钮的点击

风行水上 @ 2013-09-22 10:24:17
标签:

    回答他人的一个问题:有很多设置了-textvar的按钮,被点击时要记录被点击按钮的文字内容。

    button .btn_123 -textvar btn_textvar_123
    bindtags .btn_123 [concat [bindtags .btn_123] LogButton]
    # ... add more buttons ... #
    
    bind LogButton <Button-1> {
      puts "\$[%W cget -textvar] = [%W cget -text]"
    }
    

    主要是对Tk中事件绑定的处理:

    • bindtags命令对按钮进行标记和分类
    • bind命令绑定事件(event)
    • Button 的-command选项不支持替换

    Tk组件的tag

    Tk中的组件默认有4个tag:

    1. 组件的path,比如 ".btn_123"
    2. 组件的class,比如 "Button"
    3. 组件所在的窗口,比如 "."
    4. "all"

    tag的顺序对应事件处理的优先级。

    在"-command"选项中获知当前button的path

    button的path可以从鼠标位置获得

    set widget [winfo containing [winfo pointerx .] [winfo pointery .]]
    

    “笨”办法

    上面提到Button的"-command"选项不支持'%'替换,如果仍然希望知道当前Button的path的话,下面的方法可以一试:

    button .btn_123 -command {
      set w [lindex [info frame -1] 5 0]  ;# $w 就是要找的 path
      puts [$w cget text]
    }
    

    关键点是info frame -1命令的使用。其返回值示例如下:

    type eval line 1 cmd {.b invoke}
    

    vtcl 中的方法

    vtcl是一个用于Tcl/Tk的GUI Builder。由它生成的Tk组件进行了一定的封装。

    其生成的Tk Button的"-command"内容如下

    button $site_7_0.cpd82 \
        -command [list vTcl:DoCmdOption $site_7_0.cpd82 {puts "... %widget %top ..."}]
    
    vTcl:DefineAlias "$site_7_0.cpd82" "fg_button_2" vTcl:WidgetProc "User_Cmd" 1
    

    其中的%widget%top会被替换。

    vTcl:DefineAlias部分则通过interp alias绑定了别名。

    标签:

      分享到:
      comments powered by Disqus

      26/30ms