Where to put the MainLoop? 
Author Message
 Where to put the MainLoop?

Dear all,

By intuition I think this question is frequently asked.  Sorry if so.

I am trying to create a module that captures all STDOUT output and
display it in a Text widget.  It would be used in this way:

use GuiPerl;
$| = 1;
print "hello";  sleep 3;  print ", world\n";

My trial is

#---------------------------------------- GuiPerl.pm
package GuiPerl;
use strict;
use Tk;

my $text = tkinit->Text->pack;

sub TIEHANDLE { bless [] }

tie *STDOUT,'GuiPerl';

# MainLoop;  # No, I can't put the MainLoop here.

1

My question is where to put the MainLoop?
I don't want the MainLoop put in the program that uses my module.
It should be transparent.  So, when I remove the 'use GuiPerl;'
it becomes a normal Perl program.

Is this mission impossible?  Is there already an existing module?

Thank you.

John Lin



Mon, 23 Jun 2003 16:30:15 GMT  
 Where to put the MainLoop?
John,

At a quick glance your Tk part won't work. The standard way is to create a
new MainWindow, to pack it. Derive other widgets, like Text, from this
MainWindow. Then run MainLoop.

It should be described in the Tk-documentation. Or check out the book
"Learning Perl/Tk".

Michael

PS: here is an example, which creates a Cancel Button.

#!/usr/bin/perl -w

use Tk;

$mw=MainWindow->new;

$b=$mw->Button(-text=>"Cancel", -command=>sub{other(); })->pack;

MainLoop;

sub other {
        print "***\n";
        exit();

Quote:
}

END {
        print "---";
Quote:
}



Mon, 23 Jun 2003 22:32:15 GMT  
 Where to put the MainLoop?
"Michael Schlueter" wrote

Quote:
> At a quick glance your Tk part won't work. The standard way is to create a
> new MainWindow, to pack it. Derive other widgets, like Text, from this
> MainWindow. Then run MainLoop.

Thank you.  I know the standard way.
Sorry to make you misunderstand.  I didn't state my question clearly.

Actually I should start with a program that works.

use GuiPerl;    # module source code is below this post
$| = 1;
print "hello";  sleep 3;  print ", world\n";
Tk::MainLoop;

Please run it to see what I mean.

What I am doing is, for a console program that prints "hello, world"

$| = 1;
print "hello";  sleep 3;  print ", world\n";

I try to provide a module.  When users say "use GuiPerl" then
a MainWindow (with Text) is pop-up to act as the "console".
All the outputs from STDOUT are shown in the Text.

The problems I encounter are:

(1) The Tk::MainLoop should not appear in user's program.
    But it's hard to make it transparent.
(2) The program sleep 3 seconds then pop-up the MainWindow.
    I want the MainWindow pop-up first, show "hello", sleep 3 seconds,
    then show ", world".

All the magics should be done in the module, not in the main program
because that's what I try to provide with a module.

Can you help me with that?

Thank you.

John Lin

Quote:
>> I am trying to create a module that captures all STDOUT output and
>> display it in a Text widget.  It would be used in this way:
>> use GuiPerl;
>> $| = 1;
>> print "hello";  sleep 3;  print ", world\n";
>> My trial is
>> #---------------------------------------- GuiPerl.pm
>> package GuiPerl;
>> use strict;
>> use Tk;

>> my $text = tkinit->Text->pack;

>> sub TIEHANDLE { bless [] }

>> tie *STDOUT,'GuiPerl';

>> # MainLoop;  # No, I can't put the MainLoop here.

>> 1

>> My question is where to put the MainLoop?
>> I don't want the MainLoop put in the program that uses my module.
>> It should be transparent.  So, when I remove the 'use GuiPerl;'
>> it becomes a normal Perl program.

>> Is this mission impossible?  Is there already an existing module?

>> Thank you.

>> John Lin



Tue, 24 Jun 2003 10:56:48 GMT  
 Where to put the MainLoop?
John Lin schrieb:

Quote:
> >> I am trying to create a module that captures all STDOUT output and
> >> display it in a Text widget.  It would be used in this way:

[...]

Quote:
> >> My question is where to put the MainLoop?
> >> I don't want the MainLoop put in the program that uses my module.
> >> It should be transparent.  So, when I remove the 'use GuiPerl;'
> >> it becomes a normal Perl program.

The most natural solution would be to write an independent perl script
that catches the STDOUT output from the user script using a pipe. The
user would specify that on the command line, not by including "use
GuiPerl". Of course your script only gets activated after the user
script has finished, therefore it won't serve to monitor the progress of
a slow-running user script.

Otherwise I guess you'd have to do your own event processing without
calling MainLoop (I have but a vague idea how to do it). I think the
Tk::DoOneEvent function comes in here. Perhaps Tk::Event is the first
thing to consult; Term::Readline also looks promising.

HTH

Martin



Tue, 24 Jun 2003 20:35:58 GMT  
 Where to put the MainLoop?

Quote:

> I am trying to create a module that captures all STDOUT output and
> display it in a Text widget.  It would be used in this way:

> use GuiPerl;
> $| = 1;
> print "hello";  sleep 3;  print ", world\n";

> My trial is

> #---------------------------------------- GuiPerl.pm
> package GuiPerl;
> use strict;
> use Tk;

> my $text = tkinit->Text->pack;

> sub TIEHANDLE { bless [] }

> tie *STDOUT,'GuiPerl';

> # MainLoop;  # No, I can't put the MainLoop here.

> 1

> My question is where to put the MainLoop?

You don't need MainLoop.  Simply make

        $text->update;

the last line of the PRINT sub.  I think this will be what you want.

--
Marc Dashevsky  (remove "_" from address to reply by e-mail)



Tue, 24 Jun 2003 22:53:18 GMT  
 Where to put the MainLoop?
"Marc Dashevsky" wrote

Quote:
> John Lin says...
> > My question is where to put the MainLoop?
> You don't need MainLoop.  Simply make

> $text->update;

> the last line of the PRINT sub.  I think this will be what you want.

Wow, great!!!  It works.  Thank you very much.
Now the module becomes

package GuiPerl;
use strict;
use Tk;
my $text = tkinit->Text->pack;
sub TIEHANDLE { bless [] }

tie *STDOUT,'GuiPerl';
END { MainLoop }  # wait the user to close the application
1

I put an extra  END { MainLoop }  here so users have the
chance to do something with the output.  Is there anything
inappropriate here?

Thank you.

John Lin



Fri, 27 Jun 2003 10:37:55 GMT  
 Where to put the MainLoop?

Quote:

> package GuiPerl;
> use strict;
> use Tk;
> my $text = tkinit->Text->pack;
> sub TIEHANDLE { bless [] }

> tie *STDOUT,'GuiPerl';
> END { MainLoop }  # wait the user to close the application
> 1

> I put an extra  END { MainLoop }  here so users have the
> chance to do something with the output.  Is there anything
> inappropriate here?

I think it is a great idea.  I enhanced the GUI a little.  Perhaps you
will find some of these enhancements suitable for your use.

package GuiPerl;
use strict;
use Tk;
my $mw = tkinit;
my $text = $mw->Scrolled('Text',
        -scrollbars => 'osoe',
)->pack(
        -expand => 1,
        -fill   => 'both',
);
my $button = $mw->Button(
        -text    => 'Abort',
        -command => sub{Tk::exit},
)->pack;
$mw->update;
sub TIEHANDLE { bless [] }

tie *STDOUT,'GuiPerl';
END { $button->configure(-text => 'Close'); MainLoop }  # wait the user to close the application
1;

--
Marc Dashevsky  (remove "_" from address to reply by e-mail)



Fri, 27 Jun 2003 11:52:01 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Mainloop and Tk::Mainloop

2. Mainloop

3. command to update the mainloop during longrunning subs?

4. Undefined pTk's mainloop in package

5. Running MainLoop in background?

6. BEGIN and MAINLOOP

7. MainLoop and errors

8. How to leave the MainLoop

9. Modifying widgets outside of MainLoop

10. Exiting the MainLoop?

11. (fwd) Re: How does mainloop work?

12. (fwd) Re: How does mainloop work?

 

 
Powered by phpBB® Forum Software