Привязка двух команд к одному событию

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

$g marker bind $point <Button-1> [list $table HighLightCell 1 [expr [lindex $value 1] + 3] \; __highlight_selected $table $sparam $eyes sparam_eyes $graph]

Я также пробовал несколько других вариантов, но ни один из них не работал.

$g — это блт-граф, и он обрабатывает привязки как обычные привязки в Tk. Что происходит, так это то, что Tcl считает, что все параметры являются параметрами для $table HighLightCell, и не интерпретирует ; как конец одной команды и начало новой команды.

Я не могу использовать синтаксис {...}, потому что мне нужно поместить переменные в команды, что я не могу сделать с помощью {...}. Как я могу поместить 2 команды, которые будут выполняться, когда произойдет событие, без создания нового процесса, который будет вызывать эти команды?


person SIMEL    schedule 31.10.2012    source источник
comment
создание нового процесса намного чище - почему вы не хотите этого делать?   -  person evil otto    schedule 31.10.2012
comment
Вероятно, это даже быстрее, так как proc компилируется.   -  person schlenk    schedule 31.10.2012


Ответы (3)


Даже если я согласен с тем, что способ proc лучше, вы можете попробовать следующие два способа.

Первый заключается в использовании двойных кавычек для группировки, "...", которые похожи на фигурные скобки, но допускают раскрытие переменных и подстановку команд. Ваш код будет примерно таким:

$g marker bind $point <Button-1> "$table HighLightCell 1 [expr [lindex $value 1] + 3] ; __highlight_selected $table $sparam $eyes sparam_eyes $graph"

(Обратите внимание, что точка с запятой не экранирована.)

Второй — использовать eval и отложить на него выполнение двух команд. Вы можете попробовать это:

$g marker bind $point <Button-1> [list eval $table HighLightCell 1 [expr [lindex $value 1] + 3] \; __highlight_selected $table $sparam $eyes sparam_eyes $graph]

eval просто вызывает интерпретатор команды, сформированной его аргументами. Если среди них есть точка с запятой, команд будет две. На этот раз точка с запятой должна быть экранирована, потому что она должна интерпретироваться eval, а не раньше.

Я попробовал оба метода со следующими простыми кодами, и они оба работают:

set x 1
set y 2
pack [button .b1 -text Test1]
pack [button .b2 -text Test2]
bind .b1 <Button-1> "puts $x; puts $y"
bind .b2 <Button-2> [list eval puts $x \; puts $y]

Щелчок по любой из кнопок дает тот же результат, что и ожидалось.

1
2

Еще один момент, аргументы команды expr лучше заключать в фигурные скобки, поэтому в своем коде вы должны заменить

expr [lindex $value 1] + 3

с

expr {[lindex $value 1] + 3}

Вам не нужно беспокоиться о замене переменной $value и о выполнении команды lindex: expr сделает это за вас, но также оптимизирует выполнение. Дополнительную информацию можно найти в вики (http://wiki.tcl.tk/583), или на странице руководства expr (http://www.tcl.tk/man/tcl8.5/TclCmd/expr.htm).

person Marco Pallante    schedule 31.10.2012

Используйте + в начале следующего скрипта для привязки, например:

bind . <KeyPress-a> "puts one"
bind . <KeyPress-a> "+ puts two"
person kostix    schedule 31.10.2012

Команда list создает вызовы только одиночных команд. Это то, что он делает (ну, и строит списки, но здесь это не имеет большого значения). Вы хотите использовать две команды, поэтому вам следует поместить точку с запятой (или новую строку) снаружи двух вызовов list, которые генерируют разделенные команды, например:

$g marker bind $point <Button-1> [list \
        $table HighLightCell 1 [expr [lindex $value 1] + 3]
    ]\;[list \
        __highlight_selected $table $sparam $eyes sparam_eyes $graph]

Тем не менее, я действительно советую использовать небольшую вспомогательную процедуру на этом этапе. Это избавит вас от путаницы в долгосрочной перспективе.

proc DoSomeHighlighting {table value sparam eyes sparam_eyes graph} {
    $table HighLightCell 1 [expr {[lindex $value 1] + 3}]
    __highlight_selected $table $sparam $eyes sparam_eyes $graph
}

# Can be a number of lines of code in here, of course

$marker bind $point <1> [list DoSomeHighlighting $table $value $sparam $eyes $sparam_eyes $graph]

Это становится особенно важным, когда вы решите, что вам нужно больше вычислять значения во время выполнения.

person Donal Fellows    schedule 01.11.2012