Variables 如何在Tcl/Tk中关闭窗口时生成返回值

Variables 如何在Tcl/Tk中关闭窗口时生成返回值,variables,tcl,tk,tkentry,Variables,Tcl,Tk,Tkentry,我有一个proc,它创建了一个新窗口,要求用户提供一个数据库名称。。我希望函数在关闭后返回一个值 如何创建一个窗口以向其调用的proc返回值?我试着用以下方式来称呼它: puts "dbug:: [set top [new_db_window]]" put用于查看结果。它不起作用。在创建窗口时打印一个空的sting(“dbug::”),当我点击“确定”按钮时出现一个错误“无法读取”::新建\u db\u窗口”:没有这样的变量 该过程的代码为: proc new_db_window {} {

我有一个
proc
,它创建了一个新窗口,要求用户提供一个数据库名称。。我希望函数在关闭后返回一个值

如何创建一个窗口以向其调用的proc返回值?我试着用以下方式来称呼它:

puts "dbug:: [set top [new_db_window]]"
put
用于查看结果。它不起作用。在创建窗口时打印一个空的sting(“
dbug::
”),当我点击“确定”按钮时出现一个错误“
无法读取”::新建\u db\u窗口”:没有这样的变量

该过程的代码为:

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

}
proc new_db_window{}{
顶级。新建\u数据库\u菜单
wm title.新建数据库菜单“新建数据库”
#主机架
frame.new_db_menu.frm-浮雕“凹槽”-bd 2
grid.new_db_menu.frm
如果{[info exists db_name]}{
取消设置数据库名称
}
集合::新建数据库窗口:数据库名称“数据库”
#名称条目
设置frm\U top[帧。新建\U db\U菜单。frm.top]
设置lbl[label.new\u db\u menu.frm.top.label-文本“数据库名称:”-宽度15]
设置entr[entry.new\u db\u menu.frm.top.entry-textvariable::new\u db\u window:db\u name-width 15]
#按钮
设置b_确定[按钮.新建b_菜单.frm.ok-图像图标v-命令{返回[新建b_确定按钮]}]
设置b_否[button.new_db_menu.frm.cancel-image icon_x-command{new_db_cancel_button}]
设置sep_w[label.new_db_menu.frm.sep_w-text”“-宽度1]
设置sep_e[label.new_db_menu.frm.sep_e-text”“-宽度1]
网格$lbl-第1行-第1列-粘性w
网格$entr-第1行-第2列-粘滞w
网格$frm_顶部-第1行-第1列-第4列
网格$sep_w-第2行-第1列-粘性w
网格$b_正常-第2行-第2列-粘滞w
网格$b_编号-第2行-第3列-粘滞e
网格$sep_e-第2行-第4列-粘滞e
bind.new_db_菜单{返回[new_db_ok_按钮]}
bind.new_db_菜单{返回[new_db_ok_按钮]}
bind.new_db_菜单{new_db_cancel_按钮}
#catch按下窗口的“x”按钮
wm协议。新建\u db\u菜单wm\u删除\u窗口{
新建\u数据库\u取消\u按钮
}
#使顶部窗口无法使用
焦点$entr
抓住释放装置。
抓取设置。新建\u db\u菜单
}
proc new_db_ok_按钮{}{
新建\u数据库\u取消\u按钮
返回“$::新建数据库窗口:数据库名称”
}
proc new_db_cancel_按钮{}{
抓取集合。
销毁。新建数据库菜单
}

一种方法是使用
tkwait window$yourwindow
等待用户关闭窗口。窗口本身可能应该使用客户端代码传递给它的一些变量来管理用户输入。例如,如果需要用户输入数据库名称,请使用
entry
小部件,并使用其
-textvariable
选项将其绑定到变量。关闭窗口后,客户端代码中的
tkwait
返回,读取该变量的值

另一种方法是不使用模态窗口,而是转换为事件驱动的控制流。也就是说,使您的查询窗口接收当用户接受其输入(并且该输入已验证)时应调用的过程的名称,并在那里执行任何进一步的处理,而不是发布窗口并等待用户处理它


相关手册页面为:和(对于
-textvariable
)。

新建\u db\u取消\u按钮
过程中,您是否打算
释放抓斗?@glenn jacksman。它是有效的,我想一旦你破坏了一扇窗户,抓斗就会自动释放;模态窗口可能也应该使用
grab
。OTOH,使用8.6,您可以使用协同程序实现“简单”的交互风格,而不存在大量的模态问题…@Donal感谢您对Tcl问题的贡献。我写了很多Tcl代码,但总是从您的回答中学习。希望自己能提升到更高的技能水平。@Michael:练习。试着编写代码来做你舒适区之外的事情。挑战自己。记住,通往真理的道路不止一条。(呸!听起来太夸张了。)