Hi,
I'm trying to figure out how I can color various widgets and need some
help. I apologize for the length of the code below, but I find it is
useful for illustrating the problems.
The code below will attempt to change the foreground and background
colors for a label, entry, listbox entries, listbox highlight, listbox
selection, combo box, button, radio button, radio button item. If you
click on the "Label" button in the bottom right, it will try to change
the colors (foreground/background) for one of the label widgets and will
change the text in the button to "Entry". When you click on "Entry" it
will try to change the colors for one of the entry widgets, and will
change the button text to "Listbox". Etc. In other words, the bottom
right button will try to change the colors for one widget at a time.
Some of the color changes work, and others do not. Some of them cause
errors. Also, the "Update" button next to the 2nd listbox will populate
the list box with some entries. And the "Debug" button will print some
information about the widgets and it will also resize the window.
Suggest you click "Update" first and then select one of the list box
entries, so that you can see its color change when it gets to that step.
1) How do I change the background color of an entry widget? I can
change the foreground, but not the background.
2) Does -highlightforeground/background work for a list box?
3) Is there a way to change the background color of a Combo box entry?
4) If I don't touch the combo box, the foreground color will change
when it should (to blue), but if I make a selection first then the color
doesn't change. Why?
5) How do I change the colors of a button?
6) How do I change the colors of a radio button? Can't seem to change
the colors of the text or the button itself.
7) If I stretch the window, why doesn't the darkgray background fill
the window?
8) How do I properly attach the scroll bars to the list boxes? I'm
using grid for placement, can I mix in pack? How do I get the
scrollbars to the proper height when the list box size changes (hitting
"Update")?
9) I have no experience making a mega-widget. Would that be useful for
this code, and how do I do it?
10) If I resize the window programmatically, I sometimes have
scrollbars and sometimes I don't. Any reason why?
Thanks for any help.
Dave
<code>
use strict;
use Switch;
use Tkx;
Tkx::package_require("tile");
Tkx::package_require("style");
Tkx::package_require("BWidget");
my %g_widgets = (); # hash for all the widgets
my %g_vars = (); # hash for all the widget text variables
my $g_row = 1;
my $g_colorize = 0;
my @g_text = ("Label", "Entry", "Listbox", "Listbox Highlight", "Listbox
Select", "Combo", "Button", "Radio", "Radio Item", "Done");
MAIN:
{
InitWindow();
FillWindow();
SizeWindow();
Tkx::MainLoop;
}
sub InitWindow
{
AddMainWindow();
AddLabelEntry ("Version Number", "VersionNumber",
10, \&ValidateDateVersion);
AddLabelEntry ("Version Number Suffix",
"VersionNumberSuffix", 5, \&ValidateDateVersion);
AddLabelEntryButton ("Directory", "Directory",
30, "Update", \&UpdateDirectoryName);
AddLabelListbox ("List Box", "ListBox",
30);
AddLabelEntry ("Name", "Name",
30);
AddLabelEntryButton ("Label Entry Button",
"LabelEntryButton", 30, "Change", \&DoLabelEntryButton);
AddLabelRadio ("Radio Button", "RadioButton",
\&DoRadio);
AddLabelCombo ("Combo Box", "ComboBox",
30, "Option_1 2nd last", \&DoComboBox);
AddLabelEntry ("Notes", "Notes",
30);
AddLabelListboxButton ("Summary", "Summary",
30, "Update", \&DoSummary);
AddButton ("Debug", "Debug",
\&Debug);
$g_row++;
AddLabel ("Colorize", "Colorize");
AddButton ("Colorize", "Label",
\&Colorize);
}
sub FillWindow
{
$g_vars{VersionNumber} = "12.34";
$g_vars{VersionNumberSuffix} = "g";
$g_vars{Directory} = "current directory";
$g_vars{ListBox} = AddToList($g_vars{ListBox}, "Line 1");
$g_vars{ListBox} = AddToList($g_vars{ListBox}, " Line 2");
$g_vars{ListBox} = AddToList($g_vars{ListBox}, " 3rd Line");
$g_vars{ListBox} = AddToList($g_vars{ListBox}, " Last Line");
$g_vars{Name} = "my name";
$g_vars{LabelEntryButton} = "label entry with button";
$g_vars{ComboBox} = "2nd";
$g_vars{Notes} = "random notes";
foreach (Tkx::SplitList($g_widgets{SubFrame}->g_winfo_children))
{
Tkx::grid_configure($_, -padx => 2, -pady => 2);
}
}
sub SizeWindow
{
Tkx::update('idletasks');
Tkx::wm_geometry($g_widgets{MainWindow}, (Tkx::winfo('reqwidth',
$g_widgets{SubFrame}) + 0) . "x" .
(Tkx::winfo('reqheight', $g_widgets{SubFrame}) + 0));
}
sub AddMainWindow
{
$g_widgets{MainWindow} = Tkx::widget->new(".");
#$g_widgets{SubFrame} = $g_widgets{MainWindow}->new_frame;
#$g_widgets{SubFrame}->g_grid(-sticky => 'nsew');
$g_widgets{ScrolledWindow} =
$g_widgets{MainWindow}->new_ScrolledWindow(-managed => 0);
$g_widgets{ScrolledFrame} =
$g_widgets{ScrolledWindow}->new_ScrollableFrame();
$g_widgets{SubFrame} =
Tkx::widget->new($g_widgets{ScrolledFrame}->getframe());
$g_widgets{SubFrame}->m_configure(-background => "darkgray");
$g_widgets{ScrolledWindow}->setwidget($g_widgets{ScrolledFrame});
$g_widgets{ScrolledWindow}->g_grid(-row => 0, -column => 0, -sticky
=> "nsew");
Tkx::grid(rowconfigure => $g_widgets{MainWindow}, 0, -weight => 1);
Tkx::grid(columnconfigure => $g_widgets{MainWindow}, 0, -weight =>
1);
}
sub AddLabel
{
my ($text, $name) = @_;
my $label = $g_widgets{SubFrame}->new_ttk__label(-text => $text);
$label->configure(-font => "Times 12", -background => 'darkgray');
$label->g_grid(-column => 0, -row => $g_row, -sticky => 'e');
$g_widgets{"Label" . $name} = $label;
}
sub AddEntry
{
my ($name, $width, $command) = @_;
my $entry = $g_widgets{SubFrame}->new_ttk__entry(-width => $width,
-textvariable => \$g_vars{$name});
$entry->configure(-font => "Times 12");
$entry->configure(-validate => 'all', -validatecommand => $command)
if (defined $command);
$entry->g_grid(-column => 1, -row => $g_row, -sticky => 'w');
$g_widgets{"Entry" . $name} = $entry;
}
sub AddButton
{
my ($name, $buttonText, $buttonCommand) = @_;
my $button = $g_widgets{SubFrame}->new_ttk__button(-text =>
$buttonText, -command => $buttonCommand);
# $button->m_configure(-background => "darkgray");
$button->g_grid(-column => 3, -row => $g_row, -sticky => 'w');
$g_widgets{"Button" . $name} = $button;
}
sub AddListbox
{
my ($name, $width) = @_;
my $listbox = $g_widgets{SubFrame}->new_listbox(-width => $width,
-listvariable => \$g_vars{$name});
$listbox->configure(-font => "Courier 10");
$listbox->configure(-height => 3);
$listbox->g_grid(-column => 1, -row => $g_row, -sticky => 'w');
my $scroll = $g_widgets{SubFrame}->new_ttk__scrollbar(-orient =>
'vertical', -command => [$listbox, 'yview']);
$scroll->g_grid(-column => 2, -row => $g_row, -sticky => "w");
$listbox->configure(-yscrollcommand => [$scroll, 'set']);
$g_widgets{"Listbox" . $name} = $listbox;
$g_widgets{"Scroll" . $name} = $scroll;
}
sub AddRadio
{
my ($name, $command) = @_;
my $radio = $g_widgets{SubFrame}->new_ttk__checkbutton(-text =>
'Yes', -variable => \$g_vars{$name}, -onvalue => 1);
$radio->configure(-command => $command) if (defined $command);
$radio->g_grid(-column => 1, -row => $g_row, -sticky => 'w');
$g_widgets{"Radio" . $name} = $radio;
}
sub AddCombo
{
my ($name, $width, $list, $command) = @_;
my $combo = $g_widgets{SubFrame}->new_ttk__combobox(-textvariable =>
\$g_vars{$name});
$combo->configure(-font => "Courier 10", -width => $width);
$combo->configure(-values => $list) if (defined
$list);
$combo->g_bind("<<ComboboxSelected>>", $command) if (defined
$command);
$combo->g_grid(-column => 1, -row => $g_row, -sticky => 'w');
$g_widgets{"Combo" . $name} = $combo;
}
sub AddLabelEntry
{
my ($text, $name, $width, $command) = @_;
my $label = AddLabel($text, $name);
my $entry = AddEntry($name, $width, $command);
$g_row++;
}
sub AddLabelEntryButton
{
my ($text, $name, $width, $buttonText, $buttonCommand) = @_;
my $label = AddLabel($text, $name);
my $entry = AddEntry($name, $width); # but what if we want a
command for the entry?
my $button = AddButton($name, $buttonText, $buttonCommand);
$g_row++;
}
sub AddLabelListbox
{
my ($text, $name, $width) = @_;
my $label = AddLabel($text, $name);
my $listbox = AddListbox($name, $width);
$g_row++;
}
sub AddLabelListboxButton
{
my ($text, $name, $width, $buttonText, $buttonCommand) = @_;
my $label = AddLabel($text, $name);
my $listbox = AddListbox($name, $width);
my $button = AddButton($name, $buttonText, $buttonCommand);
$g_row++;
}
sub AddLabelRadio
{
my ($text, $name, $command) = @_;
my $label = AddLabel($text, $name);
my $radio = AddRadio($name, $command);
$g_row++;
}
sub AddLabelCombo
{
my ($text, $name, $width, $list, $command) = @_;
my $label = AddLabel($text, $name);
my $combo = AddCombo($name, $width, $list, $command);
$g_row++;
}
sub Colorize
{
$g_colorize++; # increment before switch due to errors
about to happen
$g_widgets{ButtonColorize}->configure(-text =>
$g_text[$g_colorize]);
Tkx::update();
switch ($g_colorize)
{
case "1" { $g_widgets{LabelName}->configure(-foreground =>
"blue", -background => "#000080"); }
case "2" { $g_widgets{EntryDirectory}->configure(-foreground =>
"red", -background => "#800000"); }
case "3" { $g_widgets{ListboxSummary}->configure(-foreground =>
"yellow", -background => "green"); }
case "4" {
$g_widgets{ListboxSummary}->configure(-highlightforeground => "red",
-highlightbackground => "blue"); }
case "5" {
$g_widgets{ListboxSummary}->configure(-selectforeground => "red",
-highlightbackground => "blue"); }
case "6" { $g_widgets{ComboComboBox}->configure(-foreground =>
"blue", -background => "yellow"); }
case "7" { $g_widgets{ButtonDirectory}->configure(-foreground =>
"yellow", -background => "green"); }
case "8" { $g_widgets{RadioRadioButton}->configure(-foreground
=> "blue", -background => "yellow"); }
case "9" {
$g_widgets{RadioRadioButton}->itemconfigure(-foreground => "green",
-background => "#008000"); }
}
Tkx::update();
}
sub ValidateDateVersion { print "Version: $g_vars{VersionNumber}
$g_vars{VersionNumberSuffix}\n"; }
sub UpdateDirectoryName { print "UpdateDirectoryName:
$g_vars{Directory}\n"; }
sub DoLabelEntryButton { print "DoLabelEntryButton:
$g_vars{LabelEntryButton}\n"; }
sub DoComboBox { print "DoComboBox: $g_vars{ComboBox}\n"; }
sub DoSummary
{
$g_vars{Summary} = "";
while (my ($key, $value) = each(%g_vars))
{
next if $key eq "Summary";
$g_vars{Summary} = AddToList($g_vars{Summary}, "$key = $value");
}
$g_widgets{ListboxSummary}->configure(-height =>
$g_widgets{ListboxSummary}->size());
for (my $i = 0; $i <= $g_widgets{ListboxSummary}->size(); $i += 2)
{
$g_widgets{ListboxSummary}->itemconfigure($i, -background =>
"#008000");
}
}
sub DoRadio { print "DoRadio: $g_vars{RadioButton}\n"; }
sub AddToList
{
my ($list, $str) = @_;
$list = $list . ' {' . $str . '}';
return $list;
}
sub Debug
{
print "g_vars:\n";
while (my ($key, $value) = each(%g_vars))
{
print "\t$key: $value\n";
}
print "g_widgets:\n";
while (my ($key, $value) = each(%g_widgets))
{
print "\t$key: $value\n";
}
SizeWindow();
}
</code>