如何从TK顶层窗口返回值?

时间:2014-09-29 11:17:23

标签: return tcl tk

我有一个打开TK顶层窗口的TCL脚本。在此窗口中,用户可以操作一些小部件(调用其他程序执行某些操作的按钮,检查按钮等)。当用户完成时,我希望他单击此窗口中的一个按钮,该按钮将导致顶层被破坏,并且打开它的过程将返回一个值。这就是我所拥有的:

proc openWindow {} {
    set w .testwindow
    catch {destroy $w}
    toplevel $w

    <here I setup all the widgets of the window>

    button $w.btn -text "Exit" -command {
        set ret [finishTest]
        puts "returning $ret"
        return $ret
    }

    pack $w.btn
    pack $w
}

proc finishTest {} {
    <here I evaluate the state of the $w widgets>
    if {some condition} {
        destroy $w
        return 0
    } else {
        destroy $w
        return -1
    }
}

当我调用openWindow时,窗口显示并按原样运行,当我单击“退出”按钮时,它会正确打印“returns:$ ret”但是我会调用puts [openWindow]它只会打印一个没有其他的新行单击按钮后的字符。

我定义了$ w变量globaly,以便我可以在finishTest过程中的openWindow之外访问它。

感谢您的建议!

1 个答案:

答案 0 :(得分:0)

回调不会影响局部变量,并且您的openWindow当前不会在返回之前等待回调处理。为了使其工作,您必须使用vwait(或tkwait)让事件循环运行,直到执行回调。 (它通过运行辅助事件循环来实现这一点,它确实占用了堆栈空间,因此请注意重入问题。)查看下面标记的行(finishTest未更改)。

proc openWindow {} {
    global ret;                                #########################
    set w .testwindow
    catch {destroy $w}
    toplevel $w

    <here I setup all the widgets of the window>

    button $w.btn -text "Exit" -command {
        set ret [finishTest];                  #########################
    }

    pack $w.btn
    pack $w
    vwait ret;                                 #########################
    puts "returning $ret";                     #########################
    return $ret;                               #########################
}

如果可以从coroutine内部(即可挂起的堆栈上下文)完成对openWindow的调用,则可以使用Tcl 8.6的协同程序稍微解开这个混乱。这将使代码的这一部分看起来更像(再次注意标记的行):

proc openWindow {} {
    set w .testwindow
    catch {destroy $w}
    toplevel $w

    <here I setup all the widgets of the window>

    button $w.btn -text "Exit" -command [info coroutine];   #########################

    pack $w.btn
    pack $w
    yield;                                                  #########################
    set ret [finishTest];                                   #########################
    puts "returning $ret";                                  #########################
    return $ret;                                            #########################
}