Tk::StyledButton - Stylized Button widget


        use Tk::StyledButton;
        $b = $MW->StyledButton(
                -style         => 'shiny' | 'round' | 'gel' | 'flat' | 'image',
                -shape         => 'rectangle' | 'oval' | 'round' | 'bevel' | 'folio' | [ @coords ],
                -dispersion    => fractional-number,
                -angle         => fractional-number,
                -image         => "Tk::Photo variable",
                -state         => 'normal' | 'disabled',
                -command       => [ sub {a callback} ],
                -text          => 'OK',
                -font          => $font,
                -compound      => 'left',
                -orient        => 'horizontal' | 'vertical',
                -tooltip       => 'Some helpful text'



Tk::StyledButton provides a shaped button with stylized shading, using a Tk::Canvas object to implement the button rendering. The usual Tk::Button options and behaviors are preserved as much as possible.

When a button is rendered, 2 versions are created:

idle version

This version uses the unmodified -background value to render the button.

active version

This version uses the uses a brightened version of the -background value to render the button.

If the GD (min. version 2.30) and GD::Text modules are installed, the button images can be rendered via GD and captured for external use.

Note that some option values (e.g., -shape => 'folio', -orient => 'vertical') are provided for use by Tk::StyledNB (derived from Tk::DynaTabFrame ), and have minimal value for general use.


Tk::StyledButton supports the following Tk::Button options:

-anchor -background -bitmap -command -compound -font -foreground -height -image -justify -padx -pady -state -text -textvariable -width -wraplength

In addition, the following additional options are supported:

-activeimage => Tk::Photo object

When specified with the -style => 'image' option, specifies an image to use for the entire button when active.

-angle => fractional-number

Optional shading angle for round or shiny style buttons (i.e., the position on the button which is the brightest). Can be any fractional value between 0 and 1.0; values less than 0.01 may cause divide-by-zero errors. Default depends on -shape.

-dispersion => fractional-number

Optional fractional dispersion factor applied to the shading style for the button (i.e., the amount of "spread" of bright areas). Can be any fractional value between 0 and 1.0. Default is 0.80.

-idleimage => Tk::Photo object

When specified with the -style => 'image' option, specifies an image to use for the entire button when idle.

-orient => $orientation

Optional orientation of the button. $orientation may be any of 'n', 's', 'e', 'w', 'nw', 'ne', 'sw', 'se', 'wn', 'ws', 'en', 'es'. Default is 'ne'. Intended for use with Tk::StyledNB, may not be useful for general purposes.

-shape => 'rectangle' | 'round' | 'oval' | 'bevel' | 'folio' | [ @coords ]

Optional shape for the button. Default is rectangle. Note that bevel and folio shapes are intended for Tk::StyledNB, and may not be appropriate for general use. The shape is used both to render the buttons, and to define the event binding area over the button images.

If the -style is 'image', the application may supply its own set of binding coordinates via an arrayref of polygon (X, Y) vertices, thereby permitting arbitrary bounding areas for the button (e.g., triangle, half circle, octagon, etc.) that match the appropriate edges of the image.

-style => 'shiny' | 'round' | 'gel' | 'flat' | 'image'

Optional shading style for the button. Default is shiny. 'image' indicates that the -idleimage and -activeimage option values should be used for the entire button, with the active area determined by the -shape option. This option is intended to optimize rendering for static buttons.

-tooltip => $text | [ $text, $delay ]

Optional tooltip to be attached to the button. Causes a Tk::Balloon to be attached to the bidnign area of the button, using the supplied $text and $delay. If a scalar is supplied, the default $delay is 300 milliseconds.

-usegd => 0 | 1

Causes the button to be rendered as a single GD image embedded in a Tk::Canvas, rather than a assembling the various components into a Tk::Canvas. Primarily used for the capture() method. Note that GD and GD::Text are required to support this option.

-verticaltext => 'Tk' | 'GD' | undef

Causes the text of vertically oriented buttons to be drawn using the specified method. This option is provided primarily for use by Tk::StyledNB to render left and right side tabs. If set to 'GD', the text is rendered as a GD image, then rotated 90 degrees before being embedded in the button. If set to 'Tk' (the default), the text is broken up so as to "stack" the characters vertically in the button, and the text is then rendered using the normal Tk methods. If set to undef, then the text is rendered horizontally using Tk (resulting in wide side tabs).


StyledButton is a subclass of Tk::Canvas. This widget supports the configure and cget methods described in Tk::options which can be used to enquire and modify the options described above. The widget also inherits all the methods provided by the generic Tk::Widget class.

($active_image, $active_coords, $idle_image, $idle_coords) = $button->capture( %options )

Captures the active and idle images and binding coordinates of the button in the specified $format, as defined by the GD module (default 'PNG'). Requires the installation of GD and GD::Text modules; also requires Win32::Font::NameToFile module for Win32 platforms.

$active_image and $idle_image are returned as scalars as output from the GD rendering methods. $active_coords and $idle_coords are arrayrefs of the (X, Y) polygon vertex coordinates used to create a transparent binding area on top of the images; active and idle coordinates are usually the same, but both are provided for completeness. Useful for later reusing static button images with the -style => 'image' option.

%options may include:

-format => $format

Specifies the output format of the image; can be any of 'PNG', 'GIF', or 'JPEG'. Default is 'PNG'.

-omittext => boolean

If set to a true value, any text assigned to the button will be omitted from the rendered image. Useful for creating general purpose buttons that can be overlaid with text later.

-omitimage => boolean

If set to a true value, any image assigned to the button will be omitted from the rendered button image. Useful for creating general purpose buttons that can be overlaid with an image later. If no image or text has been assigned to the button, then the -height and width values will be used to as the bounding box for the button.

-gdfont => 'string' | \&coderef

Specifies a GD-compatible font for any text to be included in the captured image; ignored if no text has been applied to the button, or the -omittext option has been set true.

Perl/Tk font specifications are not compatible with GD::Text, which only supports TrueType fonts, or the internal GD default fonts. In addition, TrueType fonts are specified to GD::Text as filenames, rather than the X11 font formats usually supported by Tk::Font.

In order to provide some means of translating between the 2 font systems, the -gdfont option provides a means to specify a GD::Text font. If the option value is a scalar, it is passed directly to the GD::Text::set_font() method; if it is a coderef, it will be called with the -family, -weight, -slant, and -size options of the current Tk::Font in use by the StyledButton, and should return a list of (fontfile, size) that can be passed to GD::Text::set_font.

Note that the filename passed to GD::Text::set_font() must either include absolute pathnames, or any of the GD::Text font environment variables must be set (e.g., FONT_PATH).

Also note that Perl/Tk can support TrueType fonts, but may apply internal modifications to render bold or italic versions; in such cases, GD::Text may be unable render the same weight or slant.

Win32 platforms may omit this option if a TrueType font is being used and its filename can be generated via Win32::Font::NameToFile.

If the -gdfont option is not specified and the font filename cannot be resolved, then a default font is selected from the GD internal font set, based on the size, weight, and slant of the button's font.

Finally, note that Perl/Tk returns font sizes in pixels, rather than points, and that GD::Text font specifications require a point, rather than pixel, size. Therefore, this module selects the proper point size to use by iterating over point sizes and computing the button text size via GD::Text until the resulting width is the same (or neary same) as the Perl/Tk computed width. This iteration may take some time to complete.

$button->flash( [ $interval ] )

Same as Tk::Button::flash() method, except that an optional interval parameter is supported.

If no $interval is specified, the behavior is the same as Tk::Button::flash(), i.e., 3 very quick flashes.

If $interval is zero, then any current flash operation is cancelled.

If $interval is non-zero, then the button rotates between the bright and dark versions every $interval milliseconds, until it is explicitly cancelled via flash(0), or any other mouse or keyboard initiated event is applied to the button.


Same as Tk::Button method.


The following examples are in the demo directory:

Simple script to display a single button. Button traits are specified via command line parameters:

Simple script to flash a button.

A simple button "studio" with the ability to interactively set various parameters for a button, and then capture the button images to a file (e.g., for use in a website's Javascript rollover navigation bar, or for use with the -style => 'image').


-underline not currently supported

Due to the limits of Canvas text elements, support for -underline is difficult, if not impossible.

-width and -height considerations

If no explicit width/height values are set, the width/height of the button is determined by the -padx/-pady values, the bounding box coordinates of any applied text, image, and/or bitmap, and the -compound setting. If no text or image is applied, the default width and height are 100 and 30, respectively.

If width or height is explicitly set, then the rendered button shape will be constrained to those parameters, which may result in scaling the button contents to fit within the specified width or height.

Button contents are scaled as follows:

  • Either -width and/or -height have been explicitly set, and the specified width/height is smaller than the bounding box computed from the text, image, and bitmap, the -padx and -pady values, and the -compound value. In this case, the button is first rendered to the computed size, then scaled to the explicitly specified dimensions.

  • When -style => 'image', and the dimensions of the activeimage and/or idleimage are smaller than the computed bounding box for any supplied text/image/bitmap, the active/idle images are first scaled up to fit the contents before the contents are supplied.

  • When -style => 'image', and -width and/or -height have been explicitly set, the active and idle images are first scaled to fit any text/image/bitmap contents, and then the result is scaled up or down as needed to fit the specified dimensions,

Values returned by $button->cget(-width, -height)

When retrieving the -width or -height via cget(), the returned value is the width/height of the enclosing Canvas object, which is usually determined by the implicit width/height computed from the defaults, or the applied text/image values.

Externally bind()ing to a StyledButton

Tk::StyledButton overrides the default widget bind() method in order to assure that any key or mouse events are bound to the transparent binding element, rather than the entire canvas. The following events are routed to the Tk::Canvas::CanvasBind() method:

        Activate          Deactivate  MapRequest
        Circulate         Destroy     Property
        CirculateRequest  Expose      Reparent
        Colormap          FocusIn     ResizeRequest
        Configure         FocusOut    Unmap
        ConfigureRequest  Gravity     Visibility
        Create            Map
capture() doesn't render -bitmap

GD doesn't provide an interface for rendering Tk's notion of bitmaps; hence, capture() will not include the -bitmap image in its rendered button.

-image and -bitmap are mutually exclusive

A StyledButton may have either image or bitmap content, but not both. If both are specified, image will take precendence (i.e., the bitmap will not be added).

Round buttons binding uses polygon, not oval

Due to a bug win Perl/TK 804.027 on Win32, transparent stipples do not work with oval items in canvases. In order to provide a binding area for -shape => 'round' | 'oval', a 12 sided polygon is used instead, which leaves some small unbound areas near the edges of the button. (oval buttons use the polygon for the rounded endcaps).

Bind area for -style => 'image'

If the dimensions of the -activeimage is different than the dimensions of the -idleimage, the bind area will be mapped to the dimensions of the smaller image.


Support -style => \&callback

Like -shape => \@vertices, this option would permit applications to provide their gradient styling, and leave the mechanics of responding to various Button events to Tk::StyledButton. Since the gradient computation is relatively isolated internally, it should be feasible to expose an interface which permits applications to supply their own gradient functions.

fix focus()
test on non-Win32 (esp fonts)
test wraplength, justify, image shape/style
figure out -underline
better round gel rendering
true aqua rendering
figure out why geometry request in DialogBox doesn't work
finish vertical/bottom StyledNB tab buttons
implement StyledNB


Copyright(C) 2006, Dean Arnold, Presicient Corp., USA. All rights reserved.

Dean Arnold

This software is provided as-is...You may use this software under the same terms as Perl itself, with the following addendum:


Tk::Button, Tk::Font, GD, GD::Text, Win32::Font::NameToFile, Tk::StyledNB, Tk::StyledDlgBox, Tk::StyledDialog


2006-01-01 Coded.