Version 22 of ttk::spinbox

Updated 2019-05-09 09:55:44 by fijeko


New command in Ttk (since tk8.5.9).

See Also

pure Tcl version


Introduced in Tk version 8.5.9.

Unlike spinbox, the -from option does not cause the value to be set, so that must be done explicitly. See Tk ticket, 2013-08-12 .


HaO 2011-05-13 The spinbox font may be set using the -font option. In Windows Vista theme, there might appear a gap between the spinbuttons.

pack [ttk::spinbox .s -font {size 20}]


In the clam or alt theme, the style option -arrowsize may be used to change the button sizes:

ttk::style theme use clam
ttk::style configure custom.TSpinbox -arrowsize 20
pack [ttk::spinbox .s -font {size 20} -style custom.TSpinbox]

Hexadecimal Display

AMG: If you want a hexadecimal display, you need to bind to the <<Decrement>> and <<Increment>> virtual events. The bind scripts must invoke [break] to inhibit normal spinbox processing, or else your hexadecimal values will be "corrected" back to the minimum.

2017-10-22: Online demo at [L1 ]

proc spinhex {win dir} {
    if {![scan [$win get] %x val]} {
        set val [$win cget -from]
    } else {
        incr val [expr {$dir * [$win cget -increment]}]
        if {[$win cget -wrap]} {
            set val [ttk::spinbox::Wrap $val [$win cget -from] [$win cget -to]]
        } else {
            set val [ttk::spinbox::Limit $val [$win cget -from] [$win cget -to]]
    $win set [format [$win cget -format] $val]
ttk::spinbox .sb -from 0 -to 255 -wrap 1 -font fixed -format "% 2X" -textvariable sb
bind .sb <<Decrement>> {spinhex %W -1; break}
bind .sb <<Increment>> {spinhex %W +1; break}
pack .sb
set sb [format [.sb cget -format] 10]

badchicken - 2017-03-27 13:29:06

I have an strange behavior that it invokes the command without stop. I write the next code in the wish8.6 console:

ttk::spinbox .sb -from 0 -to 10000 -command [list ::danitest]
grid .sb
proc ::danitest {} {
    puts "inside"
    tkwait variable ::danivar
    puts "outside"

Then, I do a single click on any arrow. The command is invoked and I can read the message "inside". Now, the process is waiting to the change of my variable danivar. At the momment, I write the next code in the console:

set ::danivar 1

and when I press enter I see that the message outside is shown, and some milliseconds later, the event is recalled (and I can read again the message "inside"). This behaviour doesn't stops.

I don't know if it is my fault or there is an error. I have the same behaviour if I use the command error instead of tkwait.

badchicken - 2017-03-28 08:10:00 (edited 2017-03-30 12:18:00

I have found the problem. When the mouse button is pressed an <<Increment>> event is generated repeatedly with the ttk::Repeatedly procedure. Inside this procedure, the ttk::spinbox::Spin procedure is called. Inside this procedure our custom command is called. After call the spinbox command the ttk::Repeatedly invokes itself with an "after" until the button is released (that cancel the repeatedly event). This works fine for me, except in 2 cases: If our command have an error command and if our command have an tkwait command (maybe could be other casuistics)

1. If our command have an error command: This cases finishes our command and continues with the ttk::Repeatedly procedure (the error affects the uplevel #0 of the spinbox but doesn't affects the uplevel #0 into the ttk::Repeatedly procedure). The error command affects the release event too and is not invoked. The result is that the repeatedly event is not canceled by the release event and is invoked by itself without stop.

2. If our command have an tkwait the problem is more simple. On click event, the ttk::Repeatedly event is invoked, and it calls to spinbox command (that will call our custom command). Then the release event is invoked but our press event is waiting in the tkwait. The repeatedly event is canceled (we are still inside of it and has no effect). When the variable (::danivar in the previous example) is modified, the code continues and the ttk::Repeatedly procedure is invoked again (after the "after cancel" command in the release event).

badchicken - 2017-03-28 08:10:00

I must edit with a third case that I think is the same as the error command:

3. If our command contains a grab command, the grab's target window will get the button release event of the spinbox.

Daneyuleb - 2019-02-28 08:10:00

I'm running into this with no tkwait, grab or error command. If I call a proc with the spinner that execs a windows executable, the spinbox often repeatedly invokes itself. TCL 8.6.9. Anyone know of a workaround other than avoiding using ttk::spinbox?

Edit: Liberal use of: ttk::CancelRepeat at the end of the invoked Command seems to be a workaround.

fijeko - 2019-05-09 09:55:44

I try to destroy the same spinbox from callback procedure and run into same problem. My solution is to set ttk::Repeat(script) to empty so that Repeatedly procedure call empty string until Release event is received.