How to implement a button whose functionality is a cross between radiobutton and checkbutton?
I want to dynamically disable or enable checkbutton
s based on the options the user selects. What I would like is a cross between radiobutton
and checkbutton
.
checkbutton .c1 -text "C1" -variable c1
checkbutton .c2 -text "C2" -variable c2
checkbutton .c3 -text "C3" -variable c3
checkbutton .c4 -text "C4" -variable c4
grid .c1 -sticky w
grid .c2 -sticky w
grid .c3 -sticky w
grid .c4 -sticky w
In the above example, if I check C1
, then the options C2
and C4
should be grayed out.
Similarly, if I check C3
then C4
should be grayed out.
It would be great if there is an elegant method which implements thi开发者_Go百科s cross between radiobutton
and checkbutton
which also scales well as the number of options increases?
By far the simplest mechanism for implementing that complex pattern of enabling and disabling is to put a trace
on the trigger variables (c1
and c3
in your example) so that whenever they change you recompute the states.
# _After_ initializing the state...
trace add variable c1 write reconfigureButtons
trace add variable c3 write reconfigureButtons
proc reconfigureButtons args {
global c1 c3
.c2 configure -state [expr {$c1 ? "disabled" : "normal"}]
.c4 configure -state [expr {$c1||$c3 ? "disabled" : "normal"}]
}
(Conceptually, you're hanging a piece of the Controller off the Model instead of off the View as is more “standard” — we don't normally talk in terms of MVC for Tk because Tk comes with built-in Controllers for most basic work — but it all works straight-forwardly and you can set it up once and not fiddle around with it afterwards.)
However, don't mix up checkbuttons and radiobuttons (as your question text seems to indicate). Please. That's because they offer different visual cues to users: checkbuttons are on-off switches, radiobuttons are “pick one of these”, and using them any other way will just make things harder to use for no other benefit.
It sounds like you just need to listen for when a checkbook is checked, and disable / enable the other boxes based on that. You might also need to keep a "disabled" count for each box, and make sure that each box is only enabled when the disable count is zero. Therefore checking C3, then C1, then C1 again, will not re-enable C4, as C4 will still have a disable count of one. Checking C3 again will in fact make the disable count of C4 zero, and C4 should be re-enabled.
You could generalize this functionality, and link the checkboxes in some descriptive manner, rather than a functional manner.
精彩评论