PerlCowboy has asked for the wisdom of the Perl Monks concerning the following question:

Good morning. I've had some production code in effect for a few years using TKX under ActiveState Perl, but had to move to Strawberry because of Windows 10 at work. I'm now using Tk and have a problem. Under TKx, it was easy to change the botton's background color, but under Tk, I'm not seeing how. The background =>"yellow" did not work. Here's my code:
#!/usr/bin/perl -w use Tk; open(OUTFILE, '>>forecast.txt') or die "Cannot open forecast.txt: $!"; my $mw = MainWindow->new; $mw->geometry("150x700"); $mw->title("Multiple Windows Test"); my $button1 = $mw->Button(-text => "18-Letters", -command => sub {print OUTFILE "18L\n", back +ground => "yellow"})->pack(-side => "top"); my $button2 = $mw->Button(-text => "07-Orders", -command => sub {print OUTFILE "07O\n"})->pa +ck(-side => "top"); my $button3 = $mw->Button(-text => "36-Letters", -command => sub {print OUTFILE "36L\n"})->pa +ck(-side => "top"); my $button4 = $mw->Button(-text => "38-Letters", -command => sub {print OUTFILE "38L\n"})->pa +ck(-side => "top"); my $button5 = $mw->Button(-text => "11-Orders", -command => sub {print OUTFILE "11O\n"})->pa +ck(-side => "top"); my $button6 = $mw->Button(-text => "99-Letters", -command => sub {print OUTFILE "99L\n"})->pa +ck(-side => "top"); my $button7 = $mw->Button(-text => "21-Letters", -command => sub {print OUTFILE "21L\n"})->pa +ck(-side => "top"); my $button8 = $mw->Button(-text => "23-Letters", -command => sub {print OUTFILE "23L\n"})->pa +ck(-side => "top"); my $button9 = $mw->Button(-text => "Return to L&I", -command => sub {print OUTFILE "OOO\n"})->pa +ck(-side => "top"); my $button10 = $mw->Button(-text => "D1008235", -command => sub {print OUTFILE "D1008235 08\ +n"})->pack(-side => "top"); my $button11 = $mw->Button(-text => "D2008235", -command => sub {print OUTFILE "D2008235 08\ +n"})->pack(-side => "top"); my $button12 = $mw->Button(-text => "D2108235", -command => sub {print OUTFILE "D2108235 08\ +n"})->pack(-side => "top"); my $button13 = $mw->Button(-text => "D2208235", -command => sub {print OUTFILE "D2208235 08\ +n"})->pack(-side => "top"); my $button14 = $mw->Button(-text => "D2608235", -command => sub {print OUTFILE "D2608235 08\ +n"})->pack(-side => "top"); my $button15 = $mw->Button(-text => "D6108 CMPRT09", -command => sub {print OUTFILE "D6108235-1\n +"})->pack(-side => "top"); my $button16 = $mw->Button(-text => "D6108 CMPRT10", -command => sub {print OUTFILE "D6108235-2\n +"})->pack(-side => "top"); my $button17 = $mw->Button(-text => "D6308 CMPRT03", -command => sub {print OUTFILE "D6308235-1\n +"})->pack(-side => "top"); my $button18 = $mw->Button(-text => "D6408235 CMPRT03", -command => sub {print OUTFILE "D6408235-1\n +"})->pack(-side => "top"); my $button19 = $mw->Button(-text => "D6608 CMPRT06", -command => sub {print OUTFILE "D6608235-06\ +n"})->pack(-side => "top"); my $button20 = $mw->Button(-text => "D6608 CMPRT25", -command => sub {print OUTFILE "D6608235-25\ +n"})->pack(-side => "top"); my $button21 = $mw->Button(-text => "D6608 CMPRT26", -command => sub {print OUTFILE "D6608235-26\ +n"})->pack(-side => "top"); my $button22 = $mw->Button(-text => "D6608 CMPRT27", -command => sub {print OUTFILE "D6608235-27\ +n"})->pack(-side => "top"); my $button23 = $mw->Button(-text => "X6108235", -command => sub {print OUTFILE "X6108235 08\ +n"})->pack(-side => "top"); my $button25 = $mw->Button(-text => "D8815235", -command => sub {print OUTFILE "D8815235 15\ +n"})->pack(-side => "top"); my $button26 = $mw->Button(-text => "M1915235", -command => sub {print OUTFILE "M1915235 15\ +n"})->pack(-side => "top"); my $button27 = $mw->Button(-text => "M9015235", -command => sub {print OUTFILE "M9015235 15\ +n"})->pack(-side => "top"); my $button28 = $mw->Button(-text => "M9115235", -command => sub {print OUTFILE "M9115235 15\ +n"})->pack(-side => "top"); my $button29 = $mw->Button(-text => "WR115235", -command => sub {print OUTFILE "WR115235 15\ +nWR415235 15\n"})->pack(-side => "top"); $mw->Button(-text => "Exit", -command => sub{$mw->destroy})->pack(); MainLoop;

Replies are listed 'Best First'.
Re: Change button color with Tk
by roboticus (Chancellor) on Oct 31, 2017 at 19:29 UTC

    PerlCowboy:

    I think it's because you need to change:

    my $button1 = $mw->Button(-text => "18-Letters", -command => sub {print OUTFILE "18L\n", back +ground => "yellow"})->pack(-side =>"top");

    to this:

    my $button1 = $mw->Button(-text => "18-Letters", -command => sub {print OUTFILE "18L\n" }, -background => "yellow"})->pack(-side =>"top +");

    I don't use Tk or Tkx, but it seems to me that:

    sub { print OUTFILE "18L\n", background => "yellow" }

    Can't possibly do what you're expecting. The print statement doesn't know anything about colors. In fact, the code is essentially equal to:

    sub { print OUTFILE "18L\n", "background", "yellow" }

    So if you look at the file you're printing to, I'd expect you'll see some unexpected "backgroundyellow" strings in there.

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      This got me a little farther, but now I need to call the subroutine when the button is clicked.
      my $button1 = $mw->Button(-text => "18-Letters", -command => sub {print OUTFILE "18L\n",\&onclick,} ,) ->pack(-side => "top"); sub onclick{ $button1->configure(-background=>"yellow") }
Re: Change button color with Tk
by kcott (Archbishop) on Nov 01, 2017 at 06:30 UTC

    G'day PerlCowboy,

    All (I can't think of any exceptions off the top of my head) Tk widget options start with a "-". See your first post here for a plethora of examples.

    All widget documentation is laid out in much the same manner. Looking at Tk::Button, you'll see Standard Options followed by Widget-Specific Options.

    The Standard Options are just a list. Their details can be found in Tk::options. At the start of that page, you'll find the cget() and configure() methods: these are what you use to query and change options (both Standard and Widget-Specific ones).

    It's unclear precisely what you want to do. If you just want to change the default background colour for your GUI when it's first presented, then ++roboticus is quite correct, you don't include them in a sub; instead, you'll want code like this:

    $parent->Button( -text => '...', -background => '...', -command => ... )

    If, however, you want a colour to change in response to an event (e.g. a button press), then you will want code in a sub, but using the configure() method I indicated above.

    — Ken

      I have some working code now, but my buttons are each a unique name. They are $button1 through $button28. Here's the code that works and the sub for the first button:
      my $button1 = $mw->Button(-text => "18-Letters", -command => sub {print OUTFILE "18L\n"}, -command => \&change)->pack(-side => "top"); sub change { $button1->configure(-background=>"yellow") }
      Aside from coding a sub for each button, could I use a if then to configure for an array? The goal is to change the color of the button once it is pressed.
      my @btn = $button1-$button28;
        Hello PerlCowboy,

        you can use a brutal method like storing all buttons into an hash:

        my $mw = MainWindow->new; my %buttons; for (1..9){ $buttons{$_} = $mw->Button(-text=>"Button $_",-command=>[\& +colorize,$_])->pack; } MainLoop; sub colorize{ $buttons{$_[0]}->configure(-bg=>'yellow'); print $buttons{$_[0]}->cget('-text')," button is yellow n +ow\n"; }

        Or you can use Canvas tagging facility to select the current one

        L*

        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.