2

I'm trying to display binary information in a widget (ie. text, entry, label). The individual characters, in this case only '0' or '1' should be clickable so that they toggle between 0 and 1.

I'm not quite sure which widget to use and how to bind a mouse event to a individual character.

I hope someone can point me into the right direction, since I'm fairly new to the TK side of things.

sebs
  • 4,566
  • 3
  • 19
  • 28
  • I'm not very good at Tk, but instead of creating a lot of bindings or widgets, I'd probably make a single canvas or image, record where the click was made and change those pixels. – potrzebie Jun 14 '13 at 02:35

1 Answers1

5

The two widgets that would make this easiest would be the canvas and the text. With the canvas, you'd either make the number string a single text item and do the conversion of click-position to character index yourself, or (more likely) make each character be its own text item. (Like that you'd be able to make each character be individually styleable and clickable with minimal effort, but you'd need to pay a bit of attention to the layout side of things.)

However, I think the text widget is probably a better fit. That lets you set tags on character ranges, and those tags are both bindable and styleable.

pack [text .t -takefocus 0]
set binstring "01011010"
set counter 0
foreach char [split $binstring ""] {
    set tag ch$counter
    .t insert end $char $tag
    .t tag bind $tag <Enter> ".t tag configure $tag -foreground red"
    .t tag bind $tag <Leave> ".t tag configure $tag -foreground black"
    .t tag bind $tag <1> [list clicked .t $tag $counter]
    incr counter
}
proc clicked {w tag counter} {
    global binstring
    # Update the display
    set idx [$w index $tag.first]
    set ch [expr {![$w get $idx]}]
    $w delete $idx
    $w insert $idx $ch $tag
    # Update the variable
    set binstring [string replace $binstring $counter $counter $ch]
    # Print the current state
    puts "binstring is now $binstring"
}
Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • If I was really doing this right, I'd make the display slaved to the variable with a trace so that you could just set the var to update the display. But for the simple case where all runtime updates come from the GUI, that's not necessary. – Donal Fellows Jun 14 '13 at 08:19
  • Thanks a lot. Thats what I was looking for. I solved it with labels in the meantime, because they are 'read only' and text can be changed by the user. One label per character. What do you mean with 'make the display slave to a variable'? – sebs Jun 16 '13 at 21:35