Как заставить окно возвращать значение при закрытии в Tcl / Tk - PullRequest
1 голос
/ 24 ноября 2011

У меня есть proc, которое создает новое окно, запрашивая у пользователя имя базы данных ... И я хочу, чтобы после закрытия функция возвращала значение.

Как мне сделать окно для возврата значения вызывающему процессу? Я попытался позвонить, используя:

puts "dbug:: [set top [new_db_window]]"

puts - увидеть результат. Не работает Печатает пустую строку ("dbug::") при создании окна и ошибку "can't read "::new_db_window": no such variable", когда я нажимаю кнопку "ОК".

Код для процедуры:

proc new_db_window {} {

    toplevel .new_db_menu


    wm title .new_db_menu "New Data Base"

    # Main Frame
    frame       .new_db_menu.frm -relief "groove" -bd 2
    grid        .new_db_menu.frm

    if {[info exists db_name]} {
        unset db_name
    }
    set ::new_db_window:db_name "Data_Base"

    # The Name Entry
    set frm_top [frame  .new_db_menu.frm.top]
    set lbl     [label  .new_db_menu.frm.top.label  -text "Database Name:" -width 15]
    set entr    [entry  .new_db_menu.frm.top.entry  -textvariable ::new_db_window:db_name -width 15]

    # The buttons
    set b_ok    [button .new_db_menu.frm.ok     -image icon_v   -command {return [new_db_ok_button]}]
    set b_no    [button .new_db_menu.frm.cancel -image icon_x   -command {new_db_cancel_button}]
    set sep_w   [label  .new_db_menu.frm.sep_w  -text ""        -width 1]
    set sep_e   [label  .new_db_menu.frm.sep_e  -text ""        -width 1]


    grid $lbl       -row 1  -column 1   -sticky w
    grid $entr      -row 1  -column 2   -sticky w
    grid $frm_top   -row 1  -column 1   -columnspan 4
    grid $sep_w     -row 2  -column 1   -sticky w
    grid $b_ok      -row 2  -column 2   -sticky w
    grid $b_no      -row 2  -column 3   -sticky e
    grid $sep_e     -row 2  -column 4   -sticky e



    bind    .new_db_menu    <Key-KP_Enter>  {return [new_db_ok_button]}
    bind    .new_db_menu    <Return>        {return [new_db_ok_button]}
    bind    .new_db_menu    <Escape>        {new_db_cancel_button}

    # catch presses on the window's `x` button
        wm protocol .new_db_menu WM_DELETE_WINDOW {
        new_db_cancel_button
    }

    # make the top window unusable
    focus $entr
    grab release .
    grab set .new_db_menu


}

proc new_db_ok_button {} {
    new_db_cancel_button
    return "$::new_db_window:db_name"
}
proc new_db_cancel_button {} {
    grab set .
    destroy .new_db_menu

}

1 Ответ

3 голосов
/ 24 ноября 2011

Один из способов - просто использовать tkwait window $yourwindow, чтобы дождаться, пока пользователь закроет окно.Само окно, вероятно, должно использовать некоторую переменную, переданную ему клиентским кодом, для управления пользовательским вводом.Например, если вам нужно, чтобы пользователь ввел имя базы данных, используйте виджет entry и свяжите его с переменной, используя опцию -textvariable.После того как окно закрыто и tkwait в коде клиента возвращается, прочитайте значение этой переменной.

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

Соответствующие справочные страницы: tkwait и options (для -textvariable).

...