Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Using a Tk window within a function

by axis3x3 (Acolyte)
on May 27, 2004 at 18:48 UTC ( [id://357009]=perlquestion: print w/replies, xml ) Need Help??

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

Hi monks, I want to use a Tk window to ask a user a question inside a function, and then return their answer as the return value.

Previously, I had code like this:

sub ask( $ ) { my $question = shift; my $textbox; $main_window = MainWindow->new; $main_window->title("Question"); $main_window->minsize(qw(400 250)); $main_window->geometry('+250+150'); $top_frame = $main_window->Frame()->pack; $middle_frame = $main_window->Frame()->pack; $bottom_frame = $main_window->Frame()->pack(-side => 'bottom'); $top_frame->Label(-height => 2)->pack; $top_frame->Label(-text => $question)->pack; $bottom_frame->Button(-text => "OK", -command => sub { goto(answer_ok2) }, -width => 10 )->pack(-padx => 2, -pady => 4); $textbox = $middle_frame->Entry(-show => $show)->pack(); MainLoop(); answer_ok2: my $ans = $textbox->get(); $main_window->destroy; return $ans; }

but this desn't work with Tk 804, so I need a better way of doing it.

The above method makes me feel dirty as we are still inside that MainLoop call when we return.

Is there some way to exit from MainLoop once it's started, or is there another cludge I can use?

Replies are listed 'Best First'.
Re: Using a Tk window within a function
by bbfu (Curate) on May 27, 2004 at 19:19 UTC

    I believe what you're looking for is a Tk::Dialog (update: er, you're right, Tk::DialogBox is what I meant). I can't test it at the moment, but I'm nearly certain that calling $Dialog->Show() (which uses $Dialog->waitVariable(\$var) internally) will process events (ie, allow user interaction) until the dialog is dismissed and then return control to your procedural code, all without a MainLoop.

    bbfu
    Black flowers blossom
    Fearless on my breath

      Thanks bbfu, I think you're right! In fact I'm going to try using Tk::DialogBox, which allows any widgets to be displayed instead of just a text box. Thank you very much!
•Re: Using a Tk window within a function
by merlyn (Sage) on May 27, 2004 at 18:55 UTC
    Hi monks, I want to use a Tk window to ask a user a question inside a function, and then return their answer as the return value.
    This is thinking "procedurally" rather than "event driven". In an event driven framework, you would simply put up a new widget somewhere with your question (perhaps in a different window, but not necessarily), and then exit your handler. Assign a callback to the "I'm done" button to trigger a new event to handle what had formerly been the second half of your subroutine.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      I agree it is, but unfortunately I'm trying to hack together a GUI version of a very procedural bit of code (the XMLTV tools for grabbing TV listings), so I'm stuck with having to do it this way.
Re: Using a Tk window within a function
by zentara (Archbishop) on May 28, 2004 at 15:13 UTC
    If this is a 1-shot query, you are probably alright doing that way in your sub. HOWEVER, if it is going to be used more than once, you do NOT want to create a new $mw in your sub, because it will cause a "memory leak", even if you destroy the $mw after use.

    What you want to do is create your $mw or $dialog just once, and withdraw it from view. Then when you enter your sub, you configure the $dialog and pop it up. That what you can reuse it on subsequent queries to the user, and you won't have "memory gain" problems.


    I'm not really a human, but I play one on earth. flash japh
      Thanks zentara, that's useful.

        Presumably I would withdraw it from view like so:

        $mainwindow->withdraw()
        Yes, and a good way to bring it out of hiding is:
        $mw->raise();
        You can also test for what state you are in:
        if ($mw->state eq 'withdrawn') { $mw->raise; } else { $mw->withdraw;

        I'm not really a human, but I play one on earth. flash japh
Re: Using a Tk window within a function
by Anonymous Monk on May 28, 2004 at 18:02 UTC
    By the way, I've discovered the answer to my original question - if you destroy all of your MainWindows, execution pops out of the end of MainLoop back into your code. I swear I tried that, but anyway it works now...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://357009]
Approved by gri6507
Front-paged by Courage
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2024-03-28 22:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found