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

I want to capture some option text as part of a script and thought that the following would do it:

use warnings; use strict; use Tk; my $main = MainWindow->new (-title => "Enter options"); my $text = $main->Text (); $text->pack(); MainLoop; my $options = join " ", $text->Contents (); print $options;

However the code fails at execution time (following exit from MainLoop) inside tk.pm, I presume trying to access $text, which I guess has been deleted.

Is there a light weight way of getting the text that has been entered into the Text widget $text?


Perl is Huffman encoded by design.

Replies are listed 'Best First'.
Re: Grabbing Text widget's contents after MainLoop
by pg (Canon) on Jul 22, 2005 at 04:45 UTC

    This is close:

    use Tk; use Tk::DialogBox; my $mw = new MainWindow(); my $dialog = $mw->DialogBox(-title => "Blah", -buttons => ["OK"]); my $content_window = $dialog->add("Text")->pack(); $dialog->Show(); my $content = $content_window->Contents(); $mw->destroy(); MainLoop; print $content;

      Close, although the empty main window is a bit naff :-)


      Perl is Huffman encoded by design.

        My original solution was sort of over kill, this one is much better and simpler:

        use Tk; use Tk::DialogBox; my $mw = new MainWindow(); my $content; my $text = $mw->Text()->pack(); my $ok = $mw->Button(-text => "OK", -command => \&grab)->pack(); MainLoop; print $content; sub grab { $content = $text->Contents(); $mw->destroy(); }
Re: Grabbing Text widget's contents after MainLoop
by graff (Chancellor) on Jul 22, 2005 at 05:20 UTC
    I'm confused. Given the OP code, just how do you "exit from MainLoop"?? There's no "quit" button or anything else...

    I presume that while the Text widget is on the screen, you intend to type something into it, and you just want to see whatever was typed there printed to stdout on exit. Is that it? Then maybe something like this:

    use strict; use Tk; my $main = MainWindow->new( -title => "Enter options:" ); my $text = $main->Text()->pack(); $main->Button(-text => "Done/Exit", -command => sub { print $text->Contents; exit(0) }, )->pack(); MainLoop;

      Use the main windows close box. Works on Windows, probably elsewhere.

      Nope. This code fragment is used in a (slightly) larger app that generally knows what to do, but sometimes needs to ask for a little help. The exit (0) is not all that useful in this case :).


      Perl is Huffman encoded by design.
        Ah -- well, that's not what I would call an "exit from MainLoop"... I'd call that (i.e. hitting the "X" button on the outer frame of the window) something like "killing the process window".

        I thought there might be a way to attach a callback sub (like the one in my reply) to the "Destroy" event for the text widget -- but I just tried that on my mac (where the "quartz" window manager puts its own frame with a "close" button around every X-windows-based Perl/Tk app), using  $text->bind("<Destroy>", sub { ...} ); and it didn't work. :(

        update: So, if the rest of your larger script is not GUI-based, and you're just popping up a window when some user input is needed, then yeah, I'd say "$main->destroy" instead of "exit(0)" in my callback on the Button widget, for sure.

Re: Grabbing Text widget's contents after MainLoop
by zentara (Cardinal) on Jul 22, 2005 at 12:14 UTC
    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = new MainWindow; $mw->title("Close test"); $mw->geometry("400x250"); my $txt = $mw->Scrolled("Text")->pack; #catches mw when closing $mw->protocol('WM_DELETE_WINDOW' => sub { print $txt->get('1.0','end'); $mw->destroy; #avoids exit }); MainLoop;

    I'm not really a human, but I play one on earth. flash japh