Автоматическое назначение команд кнопкам в Tcl/Tk

У меня есть код, в котором метки создаются автоматически из списка. Я хочу изменить метки на кнопки и назначить каждой из них команду в соответствии с их типом с некоторыми параметрами. Я пытался сделать это:

proc create_prop_menu {{inst ""}} {

    set wdth 90
    set w 20

    if {$inst == ""} {
        puts "please select a block first , then Propertires info "
    return
    }


    set cell [get_cell $inst]
    set cell_name [cell_get_name $cell]
    set inst_name [inst_get_name $inst]
    catch {destroy .prop_menu} 
    toplevel .prop_menu
    # Main Frame
    frame       .prop_menu.main_frame -relief "groove" -bd 2
    pack        .prop_menu.main_frame

    set lbl  [label .prop_menu.main_frame.cell_name_lbl -relief flat -text "Cell Name:" -width $w]
    set lbl2 [entry  .prop_menu.main_frame.cell_name -relief flat -width $wdth]
    $lbl2 insert 0 $cell_name
    $lbl2 configure -state readonly
    grid $lbl   -row 1  -column 1   -sticky nse
    grid $lbl2  -row 1  -column 2   -sticky nsw

    set r 2

    foreach fd [get_all_properties $cell] {
        set n [property_get_name $fd]
        if [cequal $n "value"] {
          set v [get_property $inst value]
        } else {
          set v [get_value_on_object $fd [get_id $cell]]
        }


        if ![cequal "NONE" $v] {
            set cmd ""
            if {[cequal $n "type"]} {
                set l "Type:"
                set t $v
            } elseif {[cequal $n "signals"]} {
                set l "Signals:"
                set t [qb_compress_names $v 1]
                set cmd [list "chose_net_from_prop" $n]
            } elseif {[cequal $n "clocks"]} {
                set l "Clocks:"
                set t [qb_compress_names $v 1]
                set cmd [list "chose_net_from_prop" $n]
            } elseif {[cequal $n "ref_supply"]} {
                set l "Reference Suply:"
                set t [qb_compress_names $v 1]
                set cmd [list "chose_net_from_prop" $n]
            } elseif {[cequal $n "stackup_file"]} {
                set l "Stackup File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "doe_file"]} {
                set l "DOE File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "lay_file"]} {
                set l "LAY File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "prs_file"]} {
                set l "PRS File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "netlist_file"]} {
                set l "NetList File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "ckt_file"]} {
                set l "CKT File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "sparam_file"]} {
                set l "S-Param File:"
                set t $v
                set cmd [list "chose_file_from_prop" $n]
            } elseif {[cequal $n "type_order"]} {
                set l "Type Order:"
                set t $v
                set cmd "chose_type_order_from_prop"
            } else {
                set l "NONE"
                    set t $v
            }
            #puts "$n -> $l -> $v"
            if {![cequal "NONE" $l]} {
                lappend cmd $inst
                if [cequal $l "Type:"] {
                    set lbl  [label  .prop_menu.main_frame.lbl_$n -relief flat -text $l -width $w]
                } else {
                    set lbl  [button .prop_menu.main_frame.lbl_$n -text $l -width $w -command "\{$cmd\}"]

                }
                set lbl2 [entry  .prop_menu.main_frame.val_$n -relief flat -width $wdth]
                $lbl2 insert 0 $t
                $lbl2 configure -state readonly
                grid $lbl  -row $r -column 1 -sticky nse
                grid $lbl2 -row $r -column 2 -sticky nsw

                set r [expr $r + 1]
            }
        }
    }
    set in "Instance_Name"
    set sep  [ttk::separator    .prop_menu.main_frame.sep       -orient horizontal]
    set lbl  [label .prop_menu.main_frame.inst_name_lbl -relief flat -text "Instance Name:" -width $w]
    set lbl2 [entry .prop_menu.main_frame.inst_name     -relief flat -width $wdth]
    $lbl2 insert 0 $inst_name
    $lbl2 configure -state readonly
    grid $sep   -row $r -columnspan 2
    grid $lbl   -row [expr $r+1] -column 1  -sticky nse
    grid $lbl2  -row [expr $r+1] -column 2  -sticky nsw 

    set ok_btn [button .prop_menu.main_frame.ok_b -text "OK" -command {prop_menu_ok_button}]
    grid $ok_btn -row [expr $r+2] -column 1 -columnspan 2 -sticky nsew

    grab release .
    grab set .prop_menu
    center_the_toplevel .prop_menu
    bind .prop_menu <Key-Return> {prop_menu_ok_button}
}

Но это не работает. Что он делает, так это то, что вместо запуска функции chose_file_from_prop с параметрами lay_file $inst он пытается запустить функцию с именем chose_file_from_prop lay_file $inst и сообщает мне, что она не существует.

Есть ли способ преодолеть это, не создавая разные функции для каждой возможной метки и не превращая $inst в глобальную переменную?


person SIMEL    schedule 20.06.2012    source источник


Ответы (1)


Если вы сгенерировали команду с list, вы можете просто использовать ее с -command без дальнейшего переноса. Не ставьте {/} вокруг него.


То есть вместо этого:

set lbl [button .prop_menu.main_frame.lbl_$n -text $l -width $w -command "\{$cmd\}"]

напишите это:

set lbl [button .prop_menu.main_frame.lbl_$n -text $l -width $w -command $cmd]
person Donal Fellows    schedule 20.06.2012