10—
The Scale Widget
0210-01.gif
A scale widget is a strange little widget. It's similar to a scrollbar because it is long and skinny with a button in the middle of it, but it doesn't scroll anything other than itself. It does keep track of something though-a number. When you change the position of the button in the scale, the value associated with the scale changes. Here are some things you can do with a scale widget:
• Create a widget from which a user can select a number between 1 and 100.
• Create three scales, each representing a value in an RGB (red, green, blue) number.
• Create four sliders, each representing a portion of an IP address. Each scale can go from 0 to 255, and it would probably be smart to start them at 255. Use a label widget to show the completed IP address, periods and all.
• Create a temperature scale that starts at -50 and goes to 130 degrees.
• Show the amount of rainfall so far this year. The scale can be marked to show every five inches.
The scale widget can be placed horizontally or vertically, depending on where you have the most room in your application window.
Creating a Scale
As with other widgets, you can create a scale by using a parent widget and passing options to the scale to change its configuration:
$parent->Scale( [ option => value ] )->pack;
Use one of the geometry managers discussed in Chapter 2, Geometry Management, to place it on the screen (such as pack, as shown in the preceding code).
Most of the options associated with the scale widget are the standard options that used with all other widgets. All of the possible options are in the following list. A discussion of special options that have a slightly different meaning for the scale and options that are specific to the scale widget follows the list.
-activebackground => color
Sets the color the slider's background should be when the cursor is over the slider (the
-state is 'active').
-background => color
Sets the color the slider's background should be when the cursor is not over the slider (
-state is 'normal'
-bigincrement => amount
Sets the amount by which the slider will change value when required to do so in large increments. Default is 0, causing the value to change by 1/10 the top value of the scale.
-borderwidth => amount
Sets the width of the edges of the widget. Default is 2.
-command => callback
Sets the callback invoked when the slider is moved.
-cursor => cursorname
Determines the cursor to display when the mouse is over the scale.
-digits => amount
Indicates how many significant digits to retain when conversion from a number to a string takes place.
-font => fontname
Sets the font used to display any text in the scale.
-foreground => color
Sets the color of the text displayed in the scale.
-from => value
Indicates the low end of the scale values. Default is 0.
-highlightbackground => color
Sets the color of the highlight rectangle displayed around the scale when it does not have the keyboard focus.
-highlightcolor => color
Sets the color of the highlight rectangle displayed around the scale when it has the keyboard focus.
-highlightthickness => amount
Sets the thickness of the highlight rectangle displayed around the scale.
-label => labelstring
Describes a label for the scale. Default is no label.
-length => amount
Sets the length of the slider (the long direction, regardless of the value of
orient) in a valid screen distance.
-orient => 'vertical' | 'horizontal'
Sets the direction the scale is drawn. Default is 'vertical'.
-relief => 'raised' | 'sunken' | 'flat' | 'ridge' | 'groove' | 'solid'
Determines how the edges of the widget are drawn. Default is 'flat'.
-repeatdelay => milliseconds
Sets the number of milliseconds the widget waits before repeating.
-repeatinterval => milliseconds
Sets the number of milliseconds the widget delays between repeats.
-resolution => value
Sets the increments by which the value in the scale will change. Default is 1.
-showvalue => 0 | 1
If set to 0, the value of the slider setting is not shown at all. Default is 1.
-sliderlength => value
Sets the size of the slider (inside the widget). Default is 25.
-state => 'normal' | 'active' | 'disabled'
Determines the state of the widget and whether or not the user can interact with it. Default is 'normal'.
-takefocus => 1 | 0 | undef
Determines whether or not the widget can receive keyboard focus. Default is to let the program decide.
-tickinterval => value
Describes the labels drawn by the right (or on the bottom) of the scale. Labels are drawn for every value. A value of 0 means no labels will be drawn at all. Default is 0.
-to => value
Sets the top value of the scale. Default is 100.
-troughcolor=> color
Sets the color of the area behind the slider button (same as a scrollbar).
-variable => \$variable
Sets the variable in which the slider value is stored.
-width => amount
Sets the width of the skinny part of the slider (regardless of the value associated with
-orient).
Assigning a Callback
As usual, use the -command option to assign a callback for the widget. The callback is invoked every time the scale value is changed. So if you change the value from 50 to 100 and the scale increment is 1, the callback will be invoked 50 times. The callback is also called when the widget is created. My recommendation is not to use -command unless you have a small number of possible values.
Orientation
To change the orientation of the scale, use the -orient option. It takes a string value that should contain either "horizontal" or "vertical". The default for this option is "vertical". Figure 10-1 shows both a horizontal scale and a vertical scale.
0213-01.gif
Figure 10-1.
Vertical scale (the default orientation) and horizontal scal
Minimum and Maximum Values
Use the -from and -to options to change the possible range of values for the scale. Usually the value associated with -from is smaller than the value associated with -to. If you happen to switch them, the scale will still display with the higher value on the right and the lower value on the left. Either or both values can be negative. Here are some examples:
$mw->Scale (-from => -10, -to => 10)->pack;
$mw->Scale (-from => 10, -to => -100)->pack;
$mw->Scale (-from => -100, -to => -50)->pack;
$mw->Scale (-from => -0.5, -to => 0.5, -resolution => 0.1)->pack;
As you can see, the values assigned to -from and -to also don't need to be whole integers.
Displayed Versus Stored Value
Sometimes the value you are searching for resides between two numbers that are very far apart, such as 0 and 1,000,000. Stepping through each of those values one by one would be tedious. You can change the step value of the displayed number using the -resolution option. The default for -resolution is 1, but it can be changed to any value that is less or greater than that.
Note that if the resolution is larger than 1, it is possible for the slider to have a value (set by the program, for example) that is smaller or larger than the displayed value.
Adding a Label
You can add a label to your scale by using the -label option. The label is placed in a different location depending on the value associated with -orient (see Figure 10-2).
0214-01.gif
Figure 10-2.
Two scales with labels
Displaying Value Increments
The scale displays its current value above or to the left of itself (depending on the value associated with -orient). Suppose you want to display labels (such as 0, 10, 20, ... 100) that show the user approximately where the button needs to be to select those values. If you want to display them underneath or to the left of the scale, you can use the -tickinterval option. By default, it is set to 0 and no numbers are displayed. To show the values every 10 numbers, use -tickinter-val => 10. The larger the range of values from which the scale can select, the larger the value this should be, or you'll end up with a bunch of numbers so close together that you won't be able to tell what they are. See Figure 10-3.
0215-01.gif
Figure 10-3.
Using-tickinterval with both horizontal and vertical scales
Changing the Size of the Scale
You can change the size of the scale by using the -length and -width options. You can also change the size of the button displayed in the slider widget; to do so, use the -sliderlength option. It takes a value specified in screen units and will change the length of the slider button. See Figure 10-4.
$mw->Scale (-sliderlength => 100); # make the button 100 pixels.
0215-02.gif
Figure 10-4.
Different-sliderlength values
Options You'll Prob0ably Never Need
The two final options for the Scale widget creation method are -bigincrement and -digits. The -bigincrement option specifies the size of jumps when using really large numbers. The default for -bigincrement is 0, which means it will jump in increments that are 1/10 the total range.
The -digits option represents how many digits will be used when converting from a number to a string. The default (0) forces the scale to use a precision that allows for a different string for every possible value on the scale.
Configuring a Scale
As usual, the scale has both configure and cget methods, which let you query and set options for the scale widget. See Appendix A for more details on how to use these methods.
Getting the Value of a Scale
The get method will return the current value of the scale:
$value = $scale->get( );
You can also specify x and y coordinates and retrieve the value of the scale at that point:
$value = $scale->get (x, y);
Setting the Value of a Scale
You can force the value associated with the scale by using the set method:
$scale->set(value);
This method is great for setting an initial value if you aren't using the -variable option at all. If you were using -variable, just set that variable to the desired starting value.
Determining Coordinates
The coords method returns a list containing x and y coordinates:
($x, $y) = $scale->coords ();
The coordinates indicate the position in which the current value is located in the scale. You can also pass in a value to find the coordinates of:
($x, $y) = $scale->coords (value);
Identifying Parts of a Scale
You can find out what part of the scale a coordinate resides in by using the identify method:
$value = $scale->identify (x, y);
The identify method returns a string containing one of the following values: "slider", "trough1", "trough2", or an empty string (if the coordinates don't refer to any of these parts).
Fun Things to Try
• Create a survey from that contains scale widgets for user information. Items such as age (0-150 would be a safe range), income, and number of children in the household can all be entered into a scale. Make good use of the -resolution, -to, and -from options to make the job easier for the user.
• Create a ping application that uses scale widgets (one for each portion of the IP address) to request an IP address from the user.