in reply to Tk -font options configuration failing

Interestingly, it seems to be a problem in Perl (or rather its XS interface), not the underlying tk. I wrote these two similar programs, one in Perl and one in Python:
#!/usr/bin/perl use warnings; use strict; use feature qw{ say }; use Tk; my $w = 'MainWindow'->new; my $t = $w->Label(-text => 'Sample', -font => ['Arial', 20, 'bold', 'u +nderline'])->pack; say ${ $t->cget('-font') }; MainLoop();

#!/usr/bin/python3 from tkinter import Tk, Label w = Tk() t = Label(text="Sample",font=['Arial', 20, 'bold', 'underline']) t.pack() print(t.cget('font')) w.mainloop()

Both of them output

Arial 20 bold underline
but only the Python one has the text actually underlined.

map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

Replies are listed 'Best First'.
Re^2: Tk -font options configuration failing
by Marshall (Canon) on Dec 26, 2023 at 07:32 UTC
    The mystery continues...
    Your Tk code works correctly on my machine. I guess a release broke something along the way.

    This is perl 5, version 24, subversion 3 (v5.24.3) built for MSWin32-x +64-multi-thread (with 1 registered patch, see perl -V for more detail)
    Tk version 804.034
Re^2: Tk -font options configuration failing
by perlboy_emeritus (Scribe) on Dec 31, 2023 at 22:16 UTC

    Hello friend Monks;

    Hacking Perl/Tk is, or can be, challenging, depending on so many factors, least of which is the totally confusing documentation. Many changes and improvements to Tk are poorly documented, with limited examples, and tutorials are rudimentary. I'd like to see a 2nd ed of "Mastering Perl/Tk" that updates Tkx, ttk and themes, but it seems Python, as ugly as it is, has eclipsed Perl. If I were younger I'd take a stab at writing a successor to that otherwise fine book. Not being one to give up easily, here be a working Tkx program that implements an improved font viewer that permits changing a named font dynamically. This works for classic widgets rather than themed widgets, but in this example I chose to mix classic and ttk widgets, just to prove a point. The key, of course, is using a named font. Comments, please?

    #!/usr/bin/env -S perl ##!/usr/bin/env -S perl -d use warnings; use strict; use v5.36; use Tkx qw/MainLoop/; # can import many more widgets: syntactic +sugar my $mw = Tkx::widget->new(".",); $mw->g_wm_title( 'Tkx/ttk Font Viewer',); $mw->g_wm_minsize(320, 200); my $f = $mw->new_ttk__frame(); my $_lab0 = $f->new_label(-text => 'Families', -width => 16, -font => 'courier', ); my $_lab1 = $f->new_label(-text => 'Size ', -width => 10, -font => 'courier', ); # # Defaults # my $family = 'Helvetica'; my $weight = 'normal'; my $slant = 'roman'; my $size = 14; my $underline = 'off'; my $overstrike = 'off'; my $cbox1 = $f->new_ttk__combobox( -values => [3 .. 32], -textvariable => \$size, -width => '6', -height => '10', ); # # Remove duplicate font names # my %fonts; my @fonts; foreach ( Tkx::SplitList( Tkx::font_families() )) { # say $_; push (@fonts, $_) unless $fonts{$_}++; } my $cbox0 = $f->new_ttk__combobox( -values => [ sort @fonts ], -textvariable => \$family, -height => '20', # number of rows to display ); my $_bQuit = $f->new_button( # classic button #my $_bQuit = $f->new_ttk__button( # themed (Aqua) button; '__' == ': +:' -text => 'Quit', -relief => 'raised', -width => 10, -command => sub { Tkx::destroy("."); } ); # # Let's create a named font from defaults... # my $fontName = Tkx::font_create('PerlboysNewFont', -family => $family, #my $fontName = $mw->Tkx::font_create( -family => $family, -size => $size, -weight => $weight, -slant => $slant, -underline => $underline, -overstrike => $overstrike, ); say $fontName; say "Named fonts: ${\Tkx::font_names()}"; # # Here be how we change the named font dynamically... # my $apply_font = sub { say "Font selected: '$family' $size $weight $slant $underline $ove +rstrike"; $fontName->Tkx::font_configure( -family => $family, -size => $size, -weight => $weight, -slant => $slant, -underline => $underline, -overstrike => $overstrike, ); }; $cbox0->Tkx::bind('<<ComboboxSelected>>', $apply_font ); $cbox1->Tkx::bind('<<ComboboxSelected>>', $apply_font ); my $stext = "Sample Text, ABCDEFghijkl, 1234567890"; my $sample = $f->new_tk__entry(-textvariable => \$stext, -width => '38', -relief => 'sunken', -font => $fontName, # the point is to use the named font :-) ); my $_cbWgt = $f->new_tk__checkbutton( -onvalue => 'bold', -offvalue => 'normal', -text => 'Weight', -variable => \$weight, -command => $apply_font, ); my $_cbSlant = $f->new_tk__checkbutton( -onvalue => 'italic', -offvalue => 'roman', -text => 'Slant', -variable => \$slant, -command => $apply_font, ); my $_cbUL = $f->new_tk__checkbutton( -text => 'Underline', -onvalue => 'on', -offvalue => 'off', -variable => \$underline, -command => $apply_font, ); my $_cbOverStrk = $f->new_tk__checkbutton( -text => 'Overstrike', -onvalue => 'on', -offvalue => 'off', -variable => \$overstrike, -command => $apply_font, ); Tkx::grid("$f"); Tkx::grid("$_lab0", "$_lab1", -sticky => 'ew',); Tkx::grid("$cbox0", "$cbox1", -sticky => 'ew', -ipadx => '2', -ipady => '4', -padx => 5, -pady => 5,); Tkx::grid("$_cbWgt", "$_cbSlant", -sticky => 'ew',); Tkx::grid("$_cbUL", "$_cbOverStrk", -sticky => 'ew',); Tkx::grid("$sample", -columnspan => '2', -ipadx => '2', -ipady => '4', -padx => 5, -pady => 5,); Tkx::grid("$_bQuit", '-',); MainLoop; say "Here be the place to perform any post-MainLoop processing..."; exit(0); __END__

    Happy New Year, one and all. Perhaps this one will be better than the last, which was awful... The four horsemen are winning.

    U P D A T E: 01/01/2024

    The code as posted works but there is a subtle semantic error that compromises the robustness and scalability of the examples, specifically re the creation of a named font. The code

    my $fontName = $mw->Tkx::font_create( -family => $family,

    yields a named font named '.'. This because the call to 'Tcl font create', 'Tkx::' becomes 'Tcl ', was from $mw. In essence, the create step used the Tcl pathName of the main window to name the new font. If you then try to create a second named font Tcl will attempt to also name it '.', which will result in a fatal error. The correct way to create a named font in Tkx with a unique name is:

    my $fontName = Tkx::font_create('PerlboysNewFont', -family => $family,

    If you then interrogate the list of named fonts with:

    say $fontName; say "Named fonts: ${\Tkx::font_names()}";

    you will see in macOS something like:

      PerlboysNewFont
      Named fonts: TkCaptionFont PerlboysNewFont TkSmallCaptionFont TkTooltipFont TkFixedFont
      TkHeadingFont TkMenuFont TkIconFont TkTextFont TkDefaultFont
    

    I have taken the liberty of correcting the posted code for those who may download it in the future.

    Will