- 1a) A color-gradient-button-maker GUI (with an 'entry' widget)
- 1b) A color-gradient-button-maker GUI with 6 spinboxes
- 1c) A color-gradient-button-maker GUI with 6 scale widgets
- 1d) A color-gradient-button-maker GUI with 6 'miniscale' widgets
0) Set general window & widget parms (win-name, win-position, win-color-scheme, fonts, widget-geometry-parms, win-size-control). 1a) Define ALL frames and sub-frames. 1b) Pack ALL framesand sub-frames. 2) Define & pack all widgets in the frames, frame by frame. 3) Define keyboard and mouse/touchpad/touch-sensitive-screen action BINDINGS, if needed. 4) Define PROCS, if needed. 5) Additional GUI initialization (typically with one or more of the procs), if needed.This structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in Tk scripts (code re-use)._________________________________________________________________As in all my scripts that use the 'pack' geometry manager (which is all of my scripts, so far), I have put the four main pack parameters --- '-side', '-anchor', '-fill', '-expand' --- on the pack command for the various frames and widgets. So Tcler's can experiment with these parameters if they want to change the behavior of the GUI when window size is changed.Alternatively, Tcler's can activate the commented statement
wm resizeable . 0 0to make the canvas a fixed size and avoid any confusion that might be caused by allowing the window to be resized.However, I wanted to be able to make a rectangle/button of almost any desired size, by resizing the window and having the canvas resize automatically. So I did not fix the size of the window.
Code for the Tk script 'make_gradient-on-canvas_externalColorSelector_2buttons.tk' :
#!/usr/bin/wish -f ## ## SCRIPT: make_gradient-on-canvas_externalColorSelector_2buttons.tk ## ## PURPOSE: This TkGUI script facilitates the creation of ## rectangular color-gradient images that can be used, for example, ## for the background of 'buttons' in GUIs such as 'toolchests'. ## ## A screen/window capture utility (like 'gnome-screenshot' on Linux) ## can be used to capture the image in a GIF or PNG file, say. ## ## Then, if necessary, an image editor (like 'mtpaint' on Linux) ## can be used to crop the window capture image to get only the ## rectangular area of the canvas containing the color-gradient ## --- or some sub-rectangle of that area. ## ## Furthermore, utilities (such as the ImageMagick 'convert' command ## on Linux) can be used to 'mirror' or 'flip' a gradient image in ## an image file (PNG or JPEG or GIF). The 'mirror' and 'flip' ## operations can be applied vertically or horizontally --- and ## can be applied multiple times, for various visual effects. ## ## Also decorations such as bevels could be applied with scripts ## using 'convert' or with interactive image editors such as 'mtpaint'. ## ## The resulting rectangular color-gradient image can then be used as a ## background in Tk widgets, such as button or canvas or label widgets ## in 'toolchests' or other types of GUIs. ## ##+########## ## GUI DESIGN: ## ## The GUI contains a rectangular CANVAS WIDGET into which the ## color gradient is drawn with canvas 'create line' commands, ## where the lines can be either horizontal (in the x direction) ## or vertical (in the y direction). ## ## In addition to the canvas widget (in a frame of the GUI window), ## in a 'buttons' frame of the GUI window are: ## - an 'Exit' button ## - 2 radiobuttons --- to indicate x or y direction for the ## color gradient ## - 2 buttons which call on an external color-selector GUI, ## to allow the user to select the 2 colors involved. ## ## The the 2 'color' buttons are used to set 2 pairs of RGB values --- ## of the form r1 g1 b1 r2 g2 b2 --- for the left-color (or top-color) ## and right-color (bottom-color) of the gradient. ## ## Examples of 2 settings using the two radiobuttons and the ## two color buttons: ## x 255 255 0 255 0 0 ## y 255 0 255 0 0 255 ## ## The first example says draw the lines horizontally starting ## from yellow on the left to red on the right. ## ## The second example says draw the lines vertically starting ## from magenta at the top to blue on the bottom. ##+####### ## METHOD: ## The seven parms (x/y r1 g1 b1 r2 g2 b2) ## are passed into a 'DrawGradient' proc that draws the lines ## within the canvas, filling the canvas with colored pixels. ## ## The 'DrawGradient' proc is called in the case of 5 'events': ## - button1-release on radiobutton 'x' ## - button1-release on radiobutton 'y' ## - a click on the color1 button ## - a click on the color2 button ## - GUI initialization ## ## The 'create line' commands issued 'across' the button ## (rectangular canvas) proceed fast enough that the canvas ## is colored with the 'gradient-of-colors' within 1 second. ## ##+######### ## REFERENCE (and credit): ## The 'DrawGradient' proc is based on a Tcl-Tk script by B. Oakley and ## Damon Courtney --- published at http://wiki.tcl.tk/6100 - ## 'Drawing Gradients on a Canvas'. (downloaded 2011sep26) ## That script draws gradients on multiple rectangular canvases, packed ## top to bottom. You need to edit that script to change colors or ## gradient direction. No GUI for entry of those parameters is provided. ##+###################################################################### ## 'CANONICAL' STRUCTURE OF THIS CODE: ## ## 0) Set general window parms (win-name,win-position,color-scheme, ## fonts, widget-geometry-parms, win-size-control). ## 1a) Define ALL frames and sub-frames. ## 1b) Pack ALL frames and sub-frames. ## 2) Define all widgets in the frames. Pack all the widgets for a frame, ## as one finishes defining the widgets in each frame. ## ## 3) Define keyboard or mouse/touchpad/touch-sensitive-screen action ## BINDINGS, if needed. ## 4) Define PROCS, if needed. ## 5) Additional GUI INITIALIZATION (typically with one or two of ## the procs), if needed. ## ##---------------------------------- ## The code structure in more detail, for this particular script: ## ## 1a) Define ALL frames: ## ## Top-level : '.fRbuttons' and '.fRcanvas' ## ## Sub-frames: none ## ## 1b) Pack ALL frames. ## ## 2) Define all widgets in the frames (and pack them): ## ## - In '.fRbuttons': ## - 1 button widget ('Exit') ## - 2 radiobuttons (for x or y gradient direction) ## - 2 'color' buttons (to call an external color selector) ## ## - In '.fRcanvas': one 'canvas' widget ## ## 3) Define bindings: ## 2 button1-release bindings -- on the 2 radiobuttons ## ## 4) Define procs: ## - 'DrawGradient' invoked by the 2 bindings and the ## 2 'color' buttons ## ## 5) Additional GUI initialization: Execute 'DrawGradient' once with ## an initial, example set of 7 parms ## --- x/y r1 g1 b1 r2 g2 b2 --- to start ## with a color-gradient in the canvas ## rather than a blank canvas. ##+######################################################################## ## DEVELOPED WITH: Tcl-Tk 8.5 on Ubuntu 9.10 (2009-october, 'Karmic Koala') ## ## $ wish ## % puts "$tcl_version $tk_version" ## ## showed ## 8.5 8.5 ## but this script should work in most previous 8.x versions, and probably ## even in some 7.x versions (if font handling is made 'old-style'). ##+####################################################################### ## MAINTENANCE HISTORY: ## Created by: Blaise Montandon 2012nov02 ## Changed by: ...... ......... 2012 ##+####################################################################### ##+####################################################################### ## Set general window parms (title,position). ##+####################################################################### wm title . "Draw-Color-Gradient in a Canvas" wm iconname . "DrawGradient" wm geometry . +15+30 ##+###################################################### ## Set the color scheme for the window and its widgets --- ## radiobuttons and spinboxes. ##+###################################################### tk_setPalette "#e0e0e0" set radbuttBKGD "#ffffff" ##+######################################################## ## Use a variable-width font for labels for the 6 spinboxes ## and the 2 radiobuttons and the Exit button text. ## Use a fixed-width font for the spinbox entry field. ##+######################################################## font create fontTEMP_varwidth \ -family {comic sans ms} \ -size -14 \ -weight bold \ -slant roman font create fontTEMP_SMALL_varwidth \ -family {comic sans ms} \ -size -12 \ -weight bold \ -slant roman ## Some other possible (similar) variable width fonts: ## Arial ## Bitstream Vera Sans ## DejaVu Sans ## Droid Sans ## FreeSans ## Liberation Sans ## Nimbus Sans L ## Trebuchet MS ## Verdana font create fontTEMP_fixedwidth \ -family {liberation mono} \ -size -14 \ -weight bold \ -slant roman font create fontTEMP_SMALL_fixedwidth \ -family {liberation mono} \ -size -12 \ -weight bold \ -slant roman ## Some other possible fixed width fonts (esp. on Linux): ## Andale Mono ## Bitstream Vera Sans Mono ## Courier 10 Pitch ## DejaVu Sans Mono ## Droid Sans Mono ## FreeMono ## Nimbus Mono L ## TlwgMono ##+########################################################### ## SET GEOM VARS FOR THE VARIOUS WIDGET DEFINITIONS. ## (e.g. width and height of canvas, and padding for Buttons) ##+########################################################### set initCanWidthPx 300 set initCanHeightPx 24 set minCanHeightPx 24 # set BDwidthPx_canvas 2 set BDwidthPx_canvas 0 ## For BUTTONS: set PADXpx_button 0 set PADYpx_button 0 set BDwidthPx_button 2 ## For LABELS: set PADXpx_label 0 set PADYpx_label 0 set BDwidthPx_label 2 ##+###################################################### ## Set a MINSIZE of the window (roughly) according to the ## approx max WIDTH of the chars in the 'fRbuttons' frame ## --- 1 exit button, 2 radiobuttons, 2 color buttons, ## and 3 labels. ## ## --- and according to the approx HEIGHT of the 2 frames ## --- 'fRbuttons' and 'fRcanvas'. ##+###################################################### set minWinWidthPx [font measure fontTEMP_varwidth \ "Exit Direction: x y Color1 Color2 Color1: #FFFF00 Color2: #FF0000"] ## Add some pixels to account for right-left-size window/widget ## border-widths (about 6 pixels) --- and borderwidths and ## padding for about 6 widgets x 4 pixels/widget. set minWinWidthPx [expr 30 + $minWinWidthPx] ## For MIN-HEIGHT: ## Allow 1 char high for 'fRbuttons', ## 24 pixels high for 'fRcanvas'. set minCharHeightPx [font metrics fontTEMP_SMALL_fixedwidth -linespace] set minWinHeightPx [expr 24 + $minCharHeightPx] ## Add some to account for top-bottom window decoration (about 20 pixels) ## and frame/widget padding (about 3 pixels/frame x 2 frames). set minWinHeightPx [expr 26 + $minWinHeightPx] ## FOR TESTING: # puts "minWinWidthPx = $minWinWidthPx" # puts "minWinHeightPx = $minWinHeightPx" wm minsize . $minWinWidthPx $minWinHeightPx ## NOTE: ## We allow the window to be resizable and we pack the canvas with ## '-fill both' so that the canvas can be enlarged by enlarging the ## window. The user can simply click-release any of the buttons ## (2 radiobuttons or 2 'color' buttons) to re-fill the canvas ## with the user-specified color gradient. ## If you want to make the window un-resizable, ## you can use the following statement. # wm resizable . 0 0 ##+################################################################ ## DEFINE *ALL* THE FRAMES: ## ## Top-level : 'fRbuttons', 'fRcanvas' ## ## Sub-frames: none ##+################################################################ ## FOR TESTING: (to check behavior of frames during window expansion) # set RELIEF_frame raised # set BDwidth_frame 2 set RELIEF_frame flat set BDwidth_frame 0 frame .fRbuttons -relief $RELIEF_frame -borderwidth $BDwidth_frame frame .fRcanvas -relief $RELIEF_frame -borderwidth $BDwidth_frame ##+############################## ## PACK the 2 top-level FRAMES. ##+############################## pack .fRbuttons \ -side top \ -anchor nw \ -fill x \ -expand 0 pack .fRcanvas \ -side top \ -anchor nw \ -fill both \ -expand 1 ## OK, the frames are defined and packed. ##+##################################### ##+##################################### ## DEFINE-AND-PACK WIDGETS WITHIN FRAMES. ##+##################################### ##+##################################### ##+################################################################ ## IN THE '.fRbuttons' FRAME -- ## DEFINE an 'Exit' BUTTON, 2 RADIOBUTTONS, 2 'color' BUTTONS, ## and 3 LABELS. ##+################################################################ button .fRbuttons.buttEXIT \ -text "Exit" \ -font fontTEMP_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command {exit} ## Define a label and 2 radiobuttons: label .fRbuttons.lab_radbutts \ -text " Gradient direction:" \ -font fontTEMP_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_button ## We set this widget-variable in the ## GUI-initialization section at the ## bottom of this script. # set curDIRECTION "x" radiobutton .fRbuttons.radbuttX \ -text "x" \ -font fontTEMP_varwidth \ -anchor w \ -variable curDIRECTION \ -value "x" \ -selectcolor "$radbuttBKGD" \ -relief flat \ -bd $BDwidthPx_button radiobutton .fRbuttons.radbuttY \ -text "y" \ -font fontTEMP_varwidth \ -anchor w \ -variable curDIRECTION \ -value "y" \ -selectcolor "$radbuttBKGD" \ -relief flat \ -bd $BDwidthPx_button ## Define the 2 color buttons. button .fRbuttons.buttCOLOR1 \ -text "Gradient Color1" \ -font fontTEMP_SMALL_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command "set_color1" button .fRbuttons.buttCOLOR2 \ -text "Gradient Color2" \ -font fontTEMP_SMALL_varwidth \ -padx $PADXpx_button \ -pady $PADYpx_button \ -relief raised \ -bd $BDwidthPx_button \ -command "set_color2" ## Define 3 labels for displaying the 2 gradient colors ## --- as hex-values and by setting background and ## foreground color of 2 of the labels. label .fRbuttons.labelCOLORS \ -text "Gradient" \ -font fontTEMP_SMALL_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label label .fRbuttons.labelCOLOR1 \ -text "" \ -font fontTEMP_SMALL_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label label .fRbuttons.labelCOLOR2 \ -text "" \ -font fontTEMP_SMALL_varwidth \ -justify left \ -anchor w \ -relief flat \ -bd $BDwidthPx_label ##+########################################### ## Pack the widgets in the 'fRbuttons' frame. ##+########################################### pack .fRbuttons.buttEXIT \ .fRbuttons.lab_radbutts \ .fRbuttons.radbuttX \ .fRbuttons.radbuttY \ .fRbuttons.buttCOLOR1 \ .fRbuttons.buttCOLOR2 \ .fRbuttons.labelCOLORS \ .fRbuttons.labelCOLOR1 \ .fRbuttons.labelCOLOR2 \ -side left \ -anchor w \ -fill none \ -expand 0 ##+######################################################## ## In the '.fRcanvas' FRAME - ## DEFINE-and-PACK CANVAS WIDGET. ##+######################################################## ## We set highlightthickness & borderwidth of the canvas to ## zero, as suggested on page 558, Chapter 37, 'The Canvas ## Widget', in the 4th edition of the book 'Practical ## Programming in Tcl and Tk'. ##+######################################################## canvas .fRcanvas.canvas \ -width $initCanWidthPx \ -height $initCanHeightPx \ -relief flat \ -highlightthickness 0 \ -borderwidth 0 pack .fRcanvas.canvas \ -side top \ -anchor nw \ -fill both \ -expand 1 ##+####################################################### ## END OF DEFINING-and-PACKING ALL WIDGETS and ## END OF DEFINING the GUI. ##+####################################################### ##+####################################################################### ## BINDINGS SECTION: ## - button1-release on each of the 2 radiobuttons ##+####################################################################### bind .fRbuttons.radbuttX <ButtonRelease-1> "DrawGradient" bind .fRbuttons.radbuttY <ButtonRelease-1> "DrawGradient" ##+###################################################################### ## PROCS SECTION: ## 'DrawGradient' - to fill the specified canvas according to the ## 7 parms --- x/y r1 g1 b1 r2 g2 b2 ## 'set_color1' - Calls on external color selector to set a ## color1, then call 'DrawGradient'. Also updates ## a color1 label in the GUI. ## 'set_color2' - Calls on external color selector to set a ## color2, then call 'DrawGradient'. Also updates ## a color2 label in the GUI. ## 'update_color1_label' - to update the color1 label widget with ## text and background-foreground colors ## 'update_color2_label' - to update the color2 label widget with ## text and background-foreground colors ##+###################################################################### ##+##################################################################### ## proc DrawGradient ##+##################################################################### ## PURPOSE: This procedure is invoked put a color gradient 'across' ## the canvas --- according to 7 parms --- x or y and ## two RGB triplets. ## ## ARGUMENTS: see the global statement ## ## CALLED BY: the COLOR1 and COLOR2 buttons (actually the 'set_color1' ## and 'set_color2' procs), 2 button1-release bindings ## on the 2 radiobuttons, and called in the GUI initialization ## section at the bottom of this script. ##+#################################################################### proc DrawGradient {} { global curDIRECTION \ COLOR1r COLOR1g COLOR1b COLOR1hex \ COLOR2r COLOR2g COLOR2b COLOR2hex ## Clear the canvas. .fRcanvas.canvas delete all ## Get current canvas width and height. set canWidthPx [winfo width .fRcanvas.canvas] set canHeightPx [winfo height .fRcanvas.canvas] ## Get the distance 'distPx' (in pixels) over which ## the 2 colors are to be gradiated. if {"$curDIRECTION" == "x"} { set distPx $canWidthPx } else { set distPx $canHeightPx } ## Get RGB ranges. set rRange [expr {double($COLOR2r - $COLOR1r)}] set gRange [expr {double($COLOR2g - $COLOR1g)}] set bRange [expr {double($COLOR2b - $COLOR1b)}] ## Calc the ratio of RGB-color-ranges to distance ## 'across' the canvas. set rRatio [expr {$rRange / $distPx}] set gRatio [expr {$gRange / $distPx}] set bRatio [expr {$bRange / $distPx}] ## Increment 'across' the canvas, drawing colored lines ## with canvas-'create line'. for {set i 0} {$i < $distPx} {incr i} { set nR [expr {int( $COLOR1r + ($rRatio * $i) )}] set nG [expr {int( $COLOR1g + ($gRatio * $i) )}] set nB [expr {int( $COLOR1b + ($bRatio * $i) )}] set hexcolor [format "#%02X%02X%02X" $nR $nG $nB] ## FOR TESTING: # puts "hexcolor = $hexcolor" if {"$curDIRECTION" == "x"} { .fRcanvas.canvas create line $i 0 $i $canHeightPx -fill "$hexcolor" } else { .fRcanvas.canvas create line 0 $i $canWidthPx $i -fill "$hexcolor" } } ## END OF for {set i 0} {$i < $distPx} {incr i} } ## END OF proc DrawGradient ##+##################################################################### ## proc 'set_color1' ##+##################################################################### ## PURPOSE: This procedure is invoked to get an RGB triplet ## via 3 RGB slider bars on the FE Color Selector GUI. ## ## Uses that RGB value to set a color to be used for the ## 1st color for a color gradient 'across' the canvas. ## ## ARGUMENTS: see the global statement ## ## OUTPUT: in global vars COLOR1r COLOR1g COLOR1b COLOR1hex ## ## CALLED BY: the COLOR1 button ##+##################################################################### proc set_color1 {} { global curDIRECTION \ COLOR1r COLOR1g COLOR1b COLOR1hex \ COLOR2r COLOR2g COLOR2b COLOR2hex # global feDIR_tkguis ## FOR TESTING: # puts "COLOR1r: $COLOR1r" # puts "COLOR1g: $COLOR1g" # puts "COLOR1b: $COLOR1b" set TEMPrgb [ exec \ ./sho_colorvals_via_sliders3rgb.tk \ $COLOR1r $COLOR1g $COLOR1b] # $feDIR_tkguis/sho_colorvals_via_sliders3rgb.tk \ ## FOR TESTING: # puts "TEMPrgb: $TEMPrgb" if { "$TEMPrgb" == "" } { return } scan $TEMPrgb "%s %s %s %s" r255 g255 b255 hexRGB set COLOR1hex "#$hexRGB" set COLOR1r $r255 set COLOR1g $g255 set COLOR1b $b255 ## Update the Color1 label. update_color1_label ## Update the color gradient on the canvas. DrawGradient } ## END OF PROC 'set_color1' ##+##################################################################### ## proc 'set_color2' ##+##################################################################### ## PURPOSE: This procedure is invoked to get an RGB triplet ## via 3 RGB slider bars on the FE Color Selector GUI. ## ## Uses that RGB value to set a color to be used for the ## 2nd color for a color gradient 'across' the canvas. ## ## ARGUMENTS: see the global statement ## ## OUTPUT: in global vars COLOR2r COLOR2g COLOR2b COLOR2hex ## ## CALLED BY: the COLOR2 button ##+##################################################################### proc set_color2 {} { global curDIRECTION \ COLOR1r COLOR1g COLOR1b COLOR1hex \ COLOR2r COLOR2g COLOR2b COLOR2hex # global feDIR_tkguis ## FOR TESTING: # puts "COLOR2r: $COLOR2r" # puts "COLOR2g: $COLOR2g" # puts "COLOR2b: $COLOR2b" set TEMPrgb [ exec \ ./sho_colorvals_via_sliders3rgb.tk \ $COLOR2r $COLOR2g $COLOR2b] # $feDIR_tkguis/sho_colorvals_via_sliders3rgb.tk \ ## FOR TESTING: # puts "TEMPrgb: $TEMPrgb" if { "$TEMPrgb" == "" } { return } scan $TEMPrgb "%s %s %s %s" r255 g255 b255 hexRGB set COLOR2hex "#$hexRGB" set COLOR2r $r255 set COLOR2g $g255 set COLOR2b $b255 ## Update the color2 label. update_color2_label ## Update the color gradient on the canvas. DrawGradient } ## END OF PROC 'set_color2' ##+##################################################################### ## proc 'update_color1_label' ##+##################################################################### ## PURPOSE: This procedure is invoked to update the color1 label ## on the GUI with text and background and foreground colors. ## ## ARGUMENTS: see the global statement ## ## OUTPUT: changed attributes of the colo1 label ## ## CALLED BY: the 'set_color1' proc and in the GUI initialization ## section at the bottom of this script. ##+##################################################################### proc update_color1_label {} { global COLOR1r COLOR1g COLOR1b COLOR1hex .fRbuttons.labelCOLOR1 configure -text "Color1 - $COLOR1hex" .fRbuttons.labelCOLOR1 configure -bg "$COLOR1hex" set RGBsum [expr { $COLOR1r + $COLOR1g + $COLOR1b }] if {$RGBsum > 400} { .fRbuttons.labelCOLOR1 configure -fg "#000000" } else { .fRbuttons.labelCOLOR1 configure -fg "#f0f0f0" } } ## END OF PROC 'update_color1_label' ##+##################################################################### ## proc 'update_color2_label' ##+##################################################################### ## PURPOSE: This procedure is invoked to update the color2 label ## on the GUI with text and background and foreground colors. ## ## ARGUMENTS: see the global statement ## ## OUTPUT: changed attributes of the colo1 label ## ## CALLED BY: the 'set_color2' proc and in the GUI initialization ## section at the bottom of this script. ##+##################################################################### proc update_color2_label {} { global COLOR2r COLOR2g COLOR2b COLOR2hex .fRbuttons.labelCOLOR2 configure -text "Color2 - $COLOR2hex" .fRbuttons.labelCOLOR2 configure -bg "$COLOR2hex" set RGBsum [expr { $COLOR2r + $COLOR2g + $COLOR2b }] if {$RGBsum > 400} { .fRbuttons.labelCOLOR2 configure -fg "#000000" } else { .fRbuttons.labelCOLOR2 configure -fg "#f0f0f0" } } ## END OF PROC 'update_color2_label' ##+############################################################# ## proc ReDraw_if_canvas_resized ## ## PURPOSE: To make sure we are only doing redraws if the ## <Configure> of the canvas resulted in a change ## in the size of the canvas. ## ## CALLED BY: bind .fRcanvas.canvas <Configure> ## at bottom of this script. ##+############################################################# proc ReDraw_if_canvas_resized {} { global PREVcanWidthPx PREVcanHeightPx set CURcanWidthPx [winfo width .fRcanvas.canvas] set CURcanHeightPx [winfo height .fRcanvas.canvas] if { $CURcanWidthPx != $PREVcanWidthPx || \ $CURcanHeightPx != $PREVcanHeightPx} { DrawGradient set PREVcanWidthPx $CURcanWidthPx set PREVcanHeightPx $CURcanHeightPx } } ## END OF ReDraw_if_canvas_resized ##+##################################################### ## Additional GUI initialization, if needed (or wanted). ##+##################################################### ## Set initial values for the 'application variables' ## --- but not widget appearance parameters (those ## are set above). ## ## Note these variables are declared global in the ## several procs --- DrawGradient, set_color1, set_color2. ## This avoids some extra memory management for temp-vars ## to pass these variables (their locations) to the procs. set curDIRECTION "x" set COLOR1r 255 set COLOR1g 255 set COLOR1b 0 set COLOR1hex [format "#%02X%02X%02X" $COLOR1r $COLOR1g $COLOR1b] set COLOR2r 255 set COLOR2g 0 set COLOR2b 0 set COLOR2hex [format "#%02X%02X%02X" $COLOR2r $COLOR2g $COLOR2b] update_color1_label update_color2_label update ## 'update' is needed before DrawGradient so that the ## canvas width and height are implemented. ## DrawGradient uses 'winfo' to get those dimensions. DrawGradient ## After this script drops into the Tk event-handling loop, ## this bind command causes redraws whenever the canvas is resized. set PREVcanWidthPx [winfo width .fRcanvas.canvas] set PREVcanHeightPx [winfo height .fRcanvas.canvas] bind .fRcanvas.canvas <Configure> "ReDraw_if_canvas_resized"
You may find this rectangle/button rather plain, even though you can get some nice color gradients.Rectangular buttons with 'shaded edges' may be more to your liking. If so, have a look atand, if you like 'rounded corners' with those 'shaded edges', trywith a large exponent.These are done using canvas-'create image', instead of canvas-'create line'.