SIMEL
SIMEL

Reputation: 8939

Is it possible to create a GUI that return a value with Tcl?

I'm creating a small piece of GUI that is a must complete for the progression of the flow. What I want is to create a proc that creates a GUI and returns 1 or 0 when the GUI is closed and then the flow continues, like this:

first part of the code
...
...
if {![open_gui]} {
    return
}
second part of the code
...
...

The GUI is simple 3 entries with a save and cancel buttons, if the save button is pressed, then some values should be stored to the data model and the function to return 1, if the cancel button is pressed, or the GUI is closed by closing the window then nothing should happen and the proc to return 0.

Is this possible?

Right now what I did is to break the code into two peaces, (code_part_1 and code_part_2) I run the first part, then open the GUI and the save button calls the second part, while the cancel just closes the GUI:

code_part_1
open_gui_split

And the function open_gui_split is:

proc open_gui_split {} {
    # ...
    set save_b [button $win.save_b -text save -command [list code_part_2]
    # ...
}

* - All the code presented is only a representation of the architecture and not the real code.

Upvotes: 1

Views: 668

Answers (1)

Donal Fellows
Donal Fellows

Reputation: 137727

It is entirely possible to create commands that run a Tk GUI, waiting for response from a user and returning that value. The key to doing that is the tkwait command:

proc popUpButton {w} {
    toplevel $w
    pack [button $w.b -text "push me" -command [list destroy $w]]
    # This waits in the event loop until $w is destroyed...
    tkwait window $w
    return "button was pushed"
}

puts "about to pop up the button"
puts ">>[popUpButton]<<"
puts "popped up the button"

tkwait comes in three varieties:

  1. tkwait window $w waits for the window $w to be destroyed.
  2. tkwait visibility $w waits for the window $w to become visible (but doesn't work on platforms other than Unix/X11).
  3. tkwait variable $varname waits for variable $varname to be set; it's just like plain Tcl vwait (and in fact vwait was originally tkwait variable before the integration of the event loop into Tcl).

Be aware that re-entering the event loop increases the stack depth and can cause your code to get very confused if you are not careful. You will probably want to use focus and grab to ensure that users only interact with the popped up dialog.

Finally, to see a more complete example of how this all works, look at the source to tk_dialog (that's exactly the version from Tk 8.4.19, direct from our repository) which is just plain old Tcl code and does the sort of thing you're after. It's a much more completely worked example than I want to write, showing off things like how to get a value to return that's based on user input.

Upvotes: 3

Related Questions