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

I have configured a Help button via Tk and find that the Text of my Help doesn't redisplay when I click the button a second time. I get the proper Window title but only a small blank little screen on the second invocation and an error message indicating, among other things

Tk::Error: font "bold14c" already exists at C:/Perl/site/lib/Tk/Submet +hods.pm line 19.

The message is referring to font(s) I created via:

$TOP->fontCreate(qw/bold14c -family courier -size 14 -weight b +old/); $TOP->fontCreate(qw/bold18h -family helvetica -size 18 -weight b +old/);

I'd like to embed a test for their existence (for those second-time-through-invocations) with something like

unless ( grep { $_->actual('-Name') =~ /bold14c/ } $TOP->fontNames ) { $TOP->fontCreate(qw/bold14c -family courier -size 14 -weight b +old/); $TOP->fontCreate(qw/bold18h -family helvetica -size 18 -weight b +old/); }

(assumes finding one font means don't need to check for the other font) but this doesn't seem to be the right way to extract the name of the font out of the object(s) that the fontNames method is kicking out for me. So the question is: how to know what the names of the fonts are since fontNames only kicks out objects?

Something that redisplays the Help screen with proper fonts is to do:

$TOP->fontDelete('bold18h', 'bold14c');

at the bottom of my sub that displays the Help (after it has succeeded) and just let the Help button do another fontCreate when reinvoked, but create/delete/create/delete/etc seems messy.

Replies are listed 'Best First'.
Re: Tk fontCreate, fontNames errors (and fontDelete seems messy)
by converter (Priest) on Jul 23, 2003 at 05:59 UTC

    When you allocate a new Tk::Font object it makes the newly defined font available to all children of the MainWindow (even if invoked against a child widget, the font is visible to the child's siblings).

    You could invoke fontCreate against your MainWindow object reference (i.e. $mw->fontCreate(...);) before calling MainLoop and then use the font when configuring your Toplevel and its child widgets. There's no need to invoke fontCreate more than once.

    If you post the relevant bits of your code it should be possible to give more direct advice.

    conv

      Ah, progress. Thank you. My mindset had been "no globals" and I was only trying to make resources such as the new font in the screen that needed them.

      As you point out, when a MainWindow invents a font, that font is available to all its children. But when I moved the fontCreate lines into the Toplevel window that was containing the Help button, I got the effect I wanted for the Help button but now that Toplevel (a child of the MainWindow) would not reinvoke because its redefinition of fonts would cause the same error.

      Moving the definition of the fonts all the way back into the first MainWindow solves the problem since the MainWindow is only invoked once, upon initialization of the program. But this need to create a "global" font for some button a few Toplevels down doesn't feel "right"....

        It sounds like you may be allocating this Toplevel each time you want to display it. You might consider allocating the Toplevel once and then mapping/unmapping it as needed. The relevant methods are withdraw and deiconify (see perldoc Tk::Wm), and raise (see perldoc Tk::Widget).

        Here is an example from page 233 of Mastering Perl/Tk:

        use Tk; $mw = MainWindow->new; $mw->title("MainWindow"); $mw->Button(-text => "Toplevel", -command => \&do_Toplevel)->pack(); MainLoop; sub do_Toplevel { if (! Exists($tl)) { $tl = $mw->Toplevel(); $tl->title("Toplevel"); $tl->Button(-text => "Close", -command => sub { $tl->withdraw })->pack; } else { $tl->deiconify(); $tl->raise(); } }

        This would allow you to invoke fontCreate in the same scope as the widget in which the font is intended to be used. The font definition would still be visible to all children of the MainWindow, but you'd have the illusion of scope and maintenance would be a bit easier.

        I've added links to several Perl/Tk-related resources to my home node (with more to come as I find time). Have a look around and you'll probably find a lot of useful information that you didn't know existed.

        conv