The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Tk::Preferences - a perl module for setting font and color preferenes in all children of a perl/Tk widget.


use Tk;

require Tk::Preferences;

$mw->SetPrefs(-prefs => \%preferences);

How This Works

To start with, let it be known that this is a ridiculously simple module, and that there are other (arguably better) ways to accomplish the same end. In particular, you should take a look at Tk::CmdLine, and Tk::ColorEditor. You might also want to take a look at using Xresources files. That being said, I have personally found this to be a preferable method of handling user-defined GUI preferences, because it's easy ... at least it seems that way to me. You be the judge ... ;-)

Let it also be known that to get this to work I had to manually insert the SetPrefs method into the Tk::* namespace. This is generally frowned upon, but it works, and so I'm not complaining.

This works by using the Tk::Walk method against what ever parent widget you call to visit each child widget. The child widget is then configured based on it's type and the data you send into SetPrefs.

Preference Data

preference data is stored in a hash format. Each key in the hash represents a type of Tk widget (Label, Menu, Checkbutton, etc.). Each value associated with the key is a hash reference containing configuration data for that type of widget. Be careful not to put invalid configure options for a given type of widget! Here is a brief example of a configuration data hash:

%preferences = (

    'ThemeID'   => "Shady Milkman",
    'Palette'   => "honeydew4",

    'Label' => {
        '-foreground    => "LightBlue4",
        '-background    => "#FFCC18",
        '-font'         => "-adobe-helvetica-medium-r-normal--10-*-*-*-*-*-*-*"
    'Button' => {
        '-background'   => "#555555",
        '-foreground'   => "#EEEEEE",
        '-font'         => "-adobe-helvetica-medium-r-normal--10-*-*-*-*-*-*-*"
    'Optionmenu' => {
        '-background'       => "LightBlue4",
        '-foreground'       => "#FFCC18",
        '-activebackground' => "#555555",
        '-activeforeground' => "#FFCC18",
        '-font'             => "-adobe-helvetica-medium-r-normal--10-*-*-*-*-*-*-*"
    'Heading'   => {
        '-background'       => "honeydew4",
        '-foreground'       => "#EEEEEE",
        '-font'             => "-adobe-courier-medium-r-normal--12-*-*-*-*-*-*-*"

The 'Palette' key sets the palette via the setPalette method.

The 'Headings' key is an example of a user-defined widget group. For example you may have a set of Label widgets which serve as headings in your application. You may want, say a larger font of different color than the rest of your Label widgets, and you might want to set the background color so that it is the same as your palette. You can easily accomplish this by flagging your Label widgets as being a Heading. Here is an example:

my $head1 = $mw->Label(-test "heading 2")->pack();

$head1->{'Heading'} = 1;

$mw->SetPrefs(-prefs => \%preferences);

When SetPrefs reaches $head1 it will see that it is of type 'Heading' rather than of type 'Label' and will configure it with the 'Heading' options rather than the 'Label' options.

The 'ThemeID' key is just an example to show that you can add any data you want to the hash, as long as you don't define any widgets to be part of a 'ThemeID' group, and there is no such thing as a Tk::ThemeID widget, you're safe to put in whatever you want.

Storing Configuration Data in a File.

yes, yes I know, that's what Xresources files are for. However, if you've taken the time to build an interface for your users to tweak their GUI, and you would like for your users to be able to store that data in a file, and then maybe come back later and tweak it again, and save it again, well here's one really, really easy way to do that. Go take a look at the Data::DumpXML module. You can use that module to do something like this:

## store your prefs

use Data::DumpXML::dump_xml;

open (PREFS, ">myAppPrefs.xml");

print PREFS Data::DumpXML::dump_xml(\%preferences);

close (PREFS);

##restore your prefs

use Data::DumpXML::Parser;

my $parser = Data::DumpXML::Parser->new();

open (PREFS, "myAppPrefs.xml");

$data = join ('', <PREFS>);

close (PREFS);

$preferences = $parser->parsestring($data);

$mw->SetPrefs(-prefs => $preferences);


the SetPrefs method has a couple more things you can do apart from just sending in a hash of configuration values

Setting Callbacks!

heck yeah! You can if you want, assign a callback to execute each time a certain type of widget is encountered, rather than setting configuration data for that widget. Your callback is called with two arguments, first a reference to the widget itself, and second a hash reference containing the arguments you sent to SetPrefs, meaning that you can access all the data in the configuration hash. Here's an example that set's off a callback each time a 'Button' widget is encountered:

$mw->SetPrefs( -prefs => \%preferences, -Button => \&ButtonCallback );

sub Button { my ($widget, $options) = @_; print "wow I found a button!\n"; }

why would you ever want to do this? Maybe you want to do something more complicated than just setting configuration options? Or maybe you're just crazy and like to celebrate the unbearable lightness of buttons being in your GUI? Who knows ... it's there if you want it though ...

Other Options

-debug 1|0

off be default, this option will 'warn' your console with debug messsages as they occur.


Andrew N. Hicox <>