in reply to how to prevent more than 1 tk Toplevel windows from opening

You need to be careful about spawning a toplevel in a sub with widgets added, because you will gain some memory for each invocation. It can be done, but Tk is not too good about cleaning up after itself, especially if secondary widgets( the label) are involved. It involves a thing called the ref-count, and has been discussed many times here in more advanced questions about unwanted memory gains in Tk programs. It is best to create 1 toplevel, and control it thru withdraw, and deiconify and raise. Here is one good way.
#!/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->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(); } }

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

Replies are listed 'Best First'.
Re^2: how to prevent more than 1 tk Toplevel windows from opening
by henry888 (Initiate) on May 17, 2008 at 18:26 UTC
    Thanks for your suggestion. I tested your code and I found one problem. If the user close the TopLevel window by clicking the X on the window's top-right corner instead of clicking the Close button., the user can not open any Toplevl window any more. Please help. Thanks
      found solution myself for my second question. OnDestroy will do the trick.. Thanks, perlmonks is a very helpful place.
      ====================== #!/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(); } } ===============
      Probably a better way than using onDestroy, is to just ignore the signal.
      if ( !Exists( $tl ) ) { $tl = $mw->Toplevel(); $tl->protocol('WM_DELETE_WINDOW' => sub { print "do nothing here\n"; }); ......

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