Search code examples
perlperltk

Perl Tk Formatting Text in a button


The code below creates Perl/Tk buttons filled with each event's details from the hash %events. Is there a way to format the text inside the buttons so that it appears in aligned columns in the manner printf prints it out on line 16.

use strict;
use Tk;

my %events;
$events{"Jazz Fest"}{city}   = "New Orleans";
$events{"Jazz Fest"}{state}   = "LA";
$events{"Jazz Fest"}{date}   = "June 6th, 2023";
$events{"Lollapalooza"}{city}   = "Chicago";
$events{"Lollapalooza"}{state}   = "IL";
$events{"Lollapalooza"}{date}   = "July 25th, 2023";
$events{"Blues Fest"}{city}   = "Chicago";
$events{"Blues Fest"}{state}   = "IL";
$events{"Blues Fest"}{date}   = "Augsut 4th, 2023";

my %data;
foreach my $event (sort keys %events) {

    printf("%-15.15s %-20.20s %-2.2s %18.18s\n", $event, $events{$event}{city}, $events{$event}{state}, $events{$event}{date});
    $data{$event} = sprintf("%-15.15s %-20.20s %-2.2s %18.18s", $event, $events{$event}{city}, $events{$event}{state}, $events{$event}{date});
    
}

my $data;

my $mw = MainWindow->new;
$mw->title("Event Clipboard Copy");
$mw->label("Pick Event Details to Copy.");

for(sort keys %data){

    my $text = $data{$_};
    $mw->Button( -text => $text, -anchor => 'w', -command => sub  {
    
    Clipboard->copy( $text );
         
        }
    )->pack( -fill => 'x' );
}

MainLoop;

Solution

  • To align the columns, set font of each button to "Courier" (or another monospaced font). There are at least two ways to do this:

    1. when creating the button
    2. assign the button to a variable and then call configure on it.
    #Setting font when creating the button
    $mw->Button( -text => $text, -anchor => 'w', -font => [-family => 'Courier'], -command => sub {
    
    #Calling configure on the button
    my $button = $mw->Button(-text => $text, -anchor => 'w', -command => sub {
    ...
    }->pack( -fill => 'x' );
    $button->configure(-font => [-family => 'Courier']);
    

    Here's how it looks with font set to Courier dialog with font set to Courier

    And without setting font:

    unaligned columns