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

Perl Gurus, The following code is very simple perl/tk code. when user clicks "Toplevel" button, it open a new toplevel window. But when the user close the main window directly, user will see some error message:
======== code ========= #!/usr/bin/perl use warnings; use strict; use Tk; my $tl; my $mw = MainWindow->new; $mw->title( "MainWindow" ); my $spawn_button = $mw->Button( -text => "Toplevel", -command => \&do_Toplevel )->pack(); MainLoop; sub do_Toplevel { $spawn_button->configure(-state=>'disabled'); if ( !Exists( $tl ) ) { $tl = $mw->Toplevel(); $tl ->OnDestroy( sub { $tl->withdraw; $spawn_button->configure(-state=>'normal'); } ); $tl->geometry('300x100+100+100'); $tl->title( "Toplevel" ); $tl->Button( -text => "Close", -command => sub { $tl->withdraw; $spawn_button->configure(-state=>'normal'); } )->pack; } else { $tl->deiconify(); $tl->raise(); } } ======================
But when the user close the main window directly, user will see some error message:
==================== error message ========= error:not a Tk object Tk::die_with_trace at destroyWinExpert.pl line 22 main::__ANON__ at c:/programs/Perl/lib/Tk/Widget.pm line 363 (eval) at c:/programs/Perl/lib/Tk/Widget.pm line 363 (eval) at c:/programs/Perl/lib/Tk/Widget.pm line 363 Tk::Widget::_Destroyed at c:/programs/Perl/lib/Tk.pm line 411 (eval) at c:/programs/Perl/lib/Tk.pm line 411 Tk::MainLoop at destroyWinExpert.pl line 13 =======
Please help !! THanks

Replies are listed 'Best First'.
Re: error:not a Tk object error, please help.
by Khen1950fx (Canon) on May 19, 2008 at 08:02 UTC
    This appears to do what you want:

    #!/usr/bin/perl use strict; use warnings; use Tk; my $t1; my $mw = MainWindow->new; $mw->title( "MainWindow" ); my $spawn_button = $mw->Button( -text => "Toplevel", -command => \&do_Toplevel )->pack; MainLoop; sub do_Toplevel { $spawn_button->configure(-state => 'normal'); if ( !Exists( $t1 ) ) { $t1 = $mw->Toplevel(); sub { $t1->withdraw; $spawn_button->configure(-state => 'disabled'); $t1->geometry('300x100+100+100'); $t1->title( "Toplevel" ); $t1->Button( -text => "Close", -command => sub { $t1->withdraw; $spawn_button->configure(-state => 'normal'); } )->pack; } } else { $t1->deiconify(); $t1->raise(); } }

    update: Strange, but the script on my computer worked, but after downloading the script from perlmonks---it doesn't work. Sorry...

    update: Fixed, it should work now.

      1. Tk::Error: Undefined subroutine &main::do_Toplevel called

      2. You essentially wrote

      if ( !Exists( $t1 ) ) { $t1 = $mw->Toplevel(); sub { # bunch of code that can never get called } }
        I didn't write that. I just had a gut feeling that OnDestroy was causing the problem, so I was focused on that. Otherwise, I agree with you.
Re: error:not a Tk object error, please help.
by Anonymous Monk on May 19, 2008 at 07:59 UTC
    What did you expect? When the MainWindow is closed, so are all its children, including $t1. You either want another MainWindow, or a Tk::Dialog .
      also $spawn_button
Re: error:not a Tk object error, please help.
by zentara (Cardinal) on May 19, 2008 at 13:37 UTC
    Didn't you see my response at Re^3: how to prevent more than 1 tk Toplevel windows from opening ? By using the onDestroy method, you will get the error because you are trying to withdraw a window as it is being destroyed. Use this to ignore the Window Manager's destroy signal.
    if ( !Exists( $tl ) ) { $tl = $mw->Toplevel(); $tl->protocol('WM_DELETE_WINDOW' => sub { print "do nothing here\n"; }); ......
    so a complete program would be

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
      zentara, Your solution is certainly the best and RIGHT one. works well. I did not notice you replied another msg on my another post. How to get notified by email when somebody replies my message ? Thank you very much !!
        Update

        Go to your Homepage, select User settings, then go to Message Settings. Then click the box "send me a message when there is a reply to my posts"

        I don't know about email notification, but you should get a message with a checkbox in the Chatterbox when you logon, showing all replies you've received. Maybe you didn't logon as henry888? Or maybe you have the Chatterbox turned off in your personal settings?


        I'm not really a human, but I play one on earth. Cogito ergo sum a bum