zentara++
rcaputo++
Thanks for the good advice!

If I understand my options correctly, I have 2 choices:

  • Funnel all child GUI requests through the parent
  • Setup new Tk mainloops for each child

    My first attempt is trying to funnel all the child GUI requests through the parent (since I don't know how to startup new Tk mainloops for the children), but I'm having problems.

    I thought to create an event handler (KidAsk) in the parent, that would do the GUI request and return the result (see code below). Uncommenting the line labeled "Verification" verifies that the event handler works (when called from the parent).

    My problem seems to be how to get this event handler to fire from the child? I first tried the commented out line labeled "Question 1", but that doesn't work (I'm guessing because the child process can't fire an event in the parent?). Next I tried creating a new event (AskEvent) for the child, and mapping that to the parent's event (KidAsk) in the same way that StdoutEvent & friends are mapped (see lines labeled "Question 2"). Apparently adding new events isn't allowed in POE::Wheel::Run, as this fires a warning message.

    So, what is the best way to do this? Am I anywhere near close?

    Thanks

    -Craig

    use strict; use warnings; use Data::Dumper; # The "use Tk" MUST be before "use POE"... use Tk; use Tk::DialogBox; use POE; use POE::Wheel::Run; # Create GUI window... my $top = $::poe_main_window; $top->geometry('300x50'); $top->title("PID=$$"); $top->protocol('WM_DELETE_WINDOW', sub{exit}); # Create button to push... $top->Button(-text=>"Don't Push Me - WAIT", -command=>sub{ print STDERR "Parent Asking User\n"; print STDERR "Got: ", AskUser("PID=$$"), "\n"; })->pack; print STDERR "Parent PID=$$\n"; my $session=_poeSetup(); # Go... $poe_kernel->run(); sub _poeSetup { my $session = POE::Session->create( inline_states=>{ KidAsk => sub { print STDERR "GUI Request from Child...\n"; my $ret=AskUser("PID=$$"); print STDERR "Got: $ret\n"; return($ret); }, KidOut => sub { my ($heap, $line, $wid)=@_[HEAP, ARG0, ARG1]; my $child = $heap->{Kids}{WID}{$wid}; print STDERR $child->PID . " OUT: $line\n"; }, KidErr => sub { my ($heap, $line, $wid)=@_[HEAP, ARG0, ARG1]; my $child = $heap->{Kids}{WID}{$wid}; print STDERR $child->PID . " ERR: $line\n"; }, KidClose => \&_DoClose, _start => sub { my ($kernel, $heap) = @_[KERNEL, HEAP]; $kernel->alias_set('GUI'); my $child = POE::Wheel::Run->new( Program => sub { print STDERR "Sleeping..."; system("sleep 3"); print STDERR "GUI Request from $$\n"; # Question 1 my $ret = $kernel->post('GUI','KidAsk'); # Question 2 my $ret = $kernel->yield('AskEvent'); print STDERR "DONE: $ret\n"; system("tail -f /etc/profile"); }, StdoutEvent => 'KidOut', StderrEvent => 'KidErr', CloseEvent => 'KidClose', # Question 2 AskEvent => 'KidAsk', ); $kernel->sig_child($child->PID, '_DoSig'); $heap->{Kids}{WID}{$child->ID} = $child; $heap->{Kids}{PID}{$child->PID} = $child; # Verification $kernel->yield('KidAsk'); } }, ); return($session); } ################################# # POE Session Supporting Routines ################################# sub _DoClose { my $wid = $_[ARG0]; my $child = $_[HEAP]{Kids}{WID}{$wid}; unless (defined $child) { print STDERR "wid $wid closed all pipes.\n"; return; } print STDERR "wid $wid closed all pipes.\n"; delete $_[HEAP]{Kids}{PID}{$child->PID}; } sub _DoSig { print STDERR "pid $_[ARG1] exited with status $_[ARG2].\n"; my $child = delete $_[HEAP]{Kids}{PID}{$_[ARG1]}; return unless defined $child; delete $_[HEAP]{Kids}{WID}{$child->ID}; } sub AskUser { my $txt = shift || 'No text passed'; print STDERR "$txt\n"; my $top = $::poe_main_window; # Create a dialog box to ask for a password... my $d = $top->DialogBox( -title=>"$txt", -buttons=>['Ok', 'Cancel'], -default_button=>'Ok', ); # Add the entry widget where user will type password... my $e = $d->add('Entry', -width=>30, -show => '*')->pack; $d->add('Label', -text => "What is your favorite color?")->pack; my $ans = $d->Show(); # If user didn't say ok... if ($ans ne "Ok") { die( "I give up, exiting...\n") }; # Get & return what the user typed... my $pw = $e->get; return($pw); }

    In reply to Solution Failure #1 by cmv
    in thread Tk Dialog From Multiple POE Processes? by cmv

    Title:
    Use:  <p> text here (a paragraph) </p>
    and:  <code> code here </code>
    to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.