| Hello, World! | Simple Widgets | Binding Events | More Widgets | Scrollbars | Menus | Canvas | Make things look Beautiful | More Information |
| We are moving to this wiki |
|---|
root = TkRoot.new() { title "Click the Button" }
button = TkButton.new(root) {
text "Hello..."
command proc {
p "...world!"
}
}
button.pack()
Which does exactly what you expect. As command
expects a block, the word proc is not necessary.
Note that a proc like here is a closure, so will
take its environment with it, knowing all (local) variables that were visible
for it, when it was created.
button.bind("Any-Key-h") {
p "...world! (key)"
}
Guess what? No go. Since the button does not have focus it does not
receive any events (OK, it does receive "Enter" and "Leave"). Press TAB once
and try again. That works. As alternative, button.focus() tries to get focus, as well.
However, we do not wish (as user) to TAB our way to the button that we need
before hitting the key on the keyboard. One way to achieve that is with:
root.bind("Any-Key-h") {
p "...world! (root)"
}
because root receives all events its subwidgets
receive! Very convenient!
| Any | Shift | Control | Alt | Meta, M | ||
| Mod1, M1 | Mod2, M2 | Mod3, M3 | Mod4, M4 | Mod5, M5 | ||
| Button1, B1 | Button2, B2 | Button3, B3 | Button4, B4 | Button5, B5 | Double | Triple |
of which two can be combined. Thus, "Any-B1" and "Control-Alt" are possible, "Shift-Double-Button3" and "Control-Shift-Alt" are not.
"Any" stands for shift/control/alt/mets/modX may be pressed, but need not. Without "Any", control and co may or may not be pressed, too. "ModX" are modifier keys. "ButtonX" are mouse buttons.
| Activate | Enter | KeyPress, Key | ButtonPress, Button | FocusIn | Map |
| Deactivate | Leave | KeyRelease | ButtonRelease | FocusOut | Unmap |
| Circulate | Colormap | Configure | Destroy | Expose | |
| Gravity | Motion | Property | Reparent | Visibility |
Of which you may guess as many as we do...
button.configure('underline'=>0)
underlines the single character in the text as indexed.
"Shift-Key-Tab" works fine under windows, but you should use "Key-ISO_Left_Tab" under unices (Thanks to Albert Wagner).
When two bindings from the same widget claim an event, only one of them receives it. If the events are effectively the same (like "Any-Key" and "Key"), the last one registered gets the event. If they differ (like "Alt-Key" and "Key"), the most specific one gets the event ("Alt-Key" in this case).
root.bind("Any-Key") { |event|
p event
p event.methods()
}
and press a key. *splash* what a wealth of information! Take your time
to look through it. The methods event.x() and event.y() exist, even for
key-events.
You might consider using
root.bind("Motion", proc{|x, y| p "(#{x}, #{y})"}, "%x %y")
but for most fields, the string obscures what it is about. Look the list up in
the Perl/Tk bindings.
It is not called when the user presses ENTER (another key often used to
traverse through entries) or when the mouse clicks a button. The first one
should be bound explicitly. For obtaining the value of a TkEntry or a TkText, we
need something slightly inconvenient:
entry = TkEntry.new(root)
var = TkVariable.new("f")
entry.textvariable(var)
entry.pack()
entry.bind("FocusOut") {
p "contains #{var.value()}"
}
but then we can grab it when the button is clicked, just as easily with var.value or set it with var.value=
widget.event_generate("Expose")
Act as if widget generated an "Expose". Typically, the bindings of this event
on a widget will cause it to redraw itself.
widget.bind("<Mine>") { p "My Event!" }
widget.event_generate("<Mine>")
The `<' and `>' are required to tell Tk that it is not one of its own
events.
See also the events thrown from TkOptionMenubutton.
| Hello, World! | Simple Widgets | Binding Events | More Widgets | Scrollbars | Menus | Canvas | Make things look Beautiful | More Information |