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

I am using Tk to write a program and in the program I have the main window and a couple smaller sub mainwindows that get opened upon certain conditions. Like if changes were made to a file and you try to exit without saving it will recognize there have been changes and pop up another window asking if you want to save. Now if I choose yes I want the program to save the file (which it does) and I want the window to close automatically (which it does not). How could I make this sub window close automatically and not have the main window exit also? Here is the code in question:
sub close { chomp(my $data = $t->get("1.0", "end")); open (TEMP, ">compare") || $t->insert("end", "Cannot open \"compare +\"\n"); print TEMP $data; close(TEMP); if ($filename ne "") { my $compare = compare($filename, "compare"); if ($compare == 0) { exit; }elsif ($compare == -1) { $status->insert("end", "There was an error while comparing!\n +"); }else{ my $sw = MainWindow->new(-title=>"Content Has Changed"); my $frame = $sw->Frame->pack(-side => 'top', -fill => 'x'); $frame->Label(-text => "Would you like to save before exiting +?")-> pack(-side => 'left', -anchor => 'w'); $frame->Button(-text => "No", -background => 'navy blue', -fo +reground => 'white', -command => sub {exit;})-> pack(-side => 'right'); $frame->Button(-text => "Yes", -background => 'navy blue', -f +oreground => 'white', -command =>\&save_and_exit)-> pack(-side => 'right'); } }else{ my $sw = MainWindow->new(-title=>"Save File?"); my $frame = $sw->Frame->pack(-side => 'top', -fill => 'x'); $frame->Label(-text => "Would you like to save before exiting?") +-> pack(-side => 'left', -anchor => 'w'); $frame->Button(-text => "No", -background => 'navy blue', -foreg +round => 'white', -command => sub {exit;})-> pack(-side => 'right'); $frame->Button(-text => "Yes", -background => 'navy blue', -fore +ground => 'white', -command =>\&save_and_exit)-> pack(-side => 'right'); } }
Any ideas?

Replies are listed 'Best First'.
Re: clsoing sub window upon execution?
by PodMaster (Abbot) on Dec 03, 2003 at 23:23 UTC
      I used the sub program way because I have the sub window do some functions before closing so I cannot call close right in the declerative region for the button. However I have a problem getting the window to close multiple times. It works fine the first time but when I call the window again it opens and then when I execute the function it errors while trying to close the second time.
      sub go_to { my $sw = $mw->Toplevel(-title=>"Go To Line"); my $frame = $sw->Frame->pack(-side => 'top', -fill => 'x'); $frame->Label(-text => "Enter Line Number:")->pack(-side => 'left', + -anchor => 'w'); $frame->Entry(-textvariable => \$line_number)-> pack(-side => 'left', -anchor => 'w', -fill => 'x', -expand => 1 +); $frame->Button(-text => "GO", -background => 'navy blue', -foregrou +nd => 'white', -command =>\&scroll_line)-> pack(-side => 'right'); sub scroll_line { $line_number = $line_number - 1; my $calc = $line_number/$line_count; $t->yviewMoveto($calc); $line_number = $line_number + 1; $sw->destroy(); } }
      As you might be able to tell the sub window is a "go to" line function in a text editor script I am writing and needs to be opened and closed multiple time during one session. How can I change it to do this more than once successfully. The error is:
      Tk::Error: Usage $widget->destroy(...) at C:\Documents and Settings\My_Name\My Documents\scripts\perl_edit.pl line 343. \&main::scroll_line Tk callback for .toplevel.frame.button Tk::__ANON__ at C:/Perl/site/lib/Tk.pm line 228 Tk::Button::butUp at C:/Perl/site/lib/Tk/Button.pm line 111 (command bound to event) destroy (1): 0 0x1a6dfe4 RV f=00080503 {}(1)(1) SV = RV(0x2104260) at 0x1a6dfe4 REFCNT = 1 FLAGS = (PADBUSY,PADMY,ROK) RV = 0x2145d78

        Whats the solution for this ??? Could you share, if you have figured it out... i know its a long time since this post! But i am working on something similar and have the same issue!

Re: clsoing sub window upon execution?
by pg (Canon) on Dec 04, 2003 at 02:33 UTC

    This can be made much simpler, by using Tk::Dialog.

    use Tk; use Tk::Dialog; use strict; use warnings; my $top = new MainWindow(-title => "demo"); my $save = $top->Button(-text => "Close", command => \&process_save)-> +pack(); MainLoop; sub process_save { my $dialog = $top->Dialog(-title => "Save?", -text => "Content ch +anged, save the changes?", -buttons => ["OK", "Cancel"]);#in real wor +ld, you only display this, if the content changed my $response = $dialog->Show(); print $response, "\n" #in real code, handle the response... }
      I am not sure dialog will work for this. I need to be able to have a blank text field to enter in a line number and then perform the scroll function. It does not appear that a dialog box allows for text insertion. Am I wrong in thinking this way? If so how would I accomplish this. I read the docs on the module and saw no option for this functionality.

        If that's what you want, then go with Tk::DialogBox, which allows you to add sub-widget. Here is a piece of demo:

        use Tk; use Tk::DialogBox; use strict; use warnings; my $top = new MainWindow(-title => "demo"); my $save = $top->Button(-text => "Goto line", command => \&process_sav +e)->pack(); my $line_num; MainLoop; sub process_save { my $dialog = $top->DialogBox(-title => "Save?", -buttons => ["OK", + "Cancel"]); $dialog->add("Entry", -text => \$line_num)->pack(); my $response = $dialog->Show(); print "[$response, $line_num]\n" #in real code, handle the respons +e... }