Subroutines and Callbacks in Perl/Tk

D

doni

Hi,

I am right now learning about Perl/TK and have a basic question
regarding subroutines and callbacks.

I was wondering how can I have the subroutine output to display in the
MainWindow if the subroutine is called using a button widget from the
MainWindow.

Here is the code that I wrote to test my above question.

#!/usr/bin/perl

use strict;
use Tk;

my $mw = MainWindow->new;
$mw->title("Demo Program");
$mw->Button(-text => "Test",
-command => sub{test()})->pack;
$mw->Button(-text => "Exit",
-command => sub{exit})->pack;
MainLoop;

sub test {
print "We have reached the subroutine part \n";
}
From the above code, I wanted the print statement "We have reached the
subroutine part" to display in the MainWindow when I press the "test"
button.

When I press the "Test" button the result is getting displayed on the
command line and not on the MainWindow.

Thanks,
doni
 
P

Paul Lalli

Hi,

I am right now learning about Perl/TK and have a basic question
regarding subroutines and callbacks.

I was wondering how can I have the subroutine output to display in the
MainWindow if the subroutine is called using a button widget from the
MainWindow.

Here is the code that I wrote to test my above question.

#!/usr/bin/perl

use strict;
use Tk;

my $mw = MainWindow->new;
$mw->title("Demo Program");
$mw->Button(-text => "Test",
-command => sub{test()})->pack;
$mw->Button(-text => "Exit",
-command => sub{exit})->pack;
MainLoop;

sub test {
print "We have reached the subroutine part \n";

}

subroutine part" to display in the MainWindow when I press the "test"
button.

When I press the "Test" button the result is getting displayed on the
command line and not on the MainWindow.

You are very confused about what Perl/Tk is. It is not a different
kind of Perl. All the functions that you learned in Perl do *exactly*
what they do when you `use Tk;`. Nothing's changed. print() still
prints to standard output.

If you want to put a message in your MainWindow, create a Label widget
in the main window, with a -textvariable attribute. Then when you
push the test button, change the contents of that variable.

Paul Lalli
 
B

Ben Morrow

Quoth "Paul Lalli said:
I was wondering how can I have the subroutine output to display in the
MainWindow if the subroutine is called using a button widget from the
MainWindow.
[ snip code ]

When I press the "Test" button the result is getting displayed on the
command line and not on the MainWindow.

You are very confused about what Perl/Tk is. It is not a different
kind of Perl. All the functions that you learned in Perl do *exactly*
what they do when you `use Tk;`. Nothing's changed. print() still
prints to standard output.

If you want to put a message in your MainWindow, create a Label widget
in the main window, with a -textvariable attribute. Then when you
push the test button, change the contents of that variable.

You may find the following useful: it's what I use to give a basically
command-line program a simple GUI.

Usage is as

#!/usr/bin/perl

use BMORROW::Tie::TkWatch qw/Run/;

Run {
print "Hello world!\n";
warn "Houston, we have a problem";
} 'My Perl App';

__END__

I call the module BMORROW::Tie::TkWatch (I have a convention that
modules for my own use are prefixed with my CPAN id); you probably want
to call it something else.

Ben

package BMORROW::Tie::TkWatch;

use warnings;
use strict;

our @EXPORT_OK = qw/Run Dialog Update/;
use base qw/Exporter/;

use Tk;
use Tk::Dialog;
use Scalar::Util qw/openhandle/;

my %TK;

$TK{mw} = Tk::MainWindow->new(
-title => 'Perl',
);
$TK{font} = $TK{mw}->Font(
-family => 'Bitstream Vera Sans Mono',
-size => 10,
);
$TK{out} = $TK{mw}->Scrolled(
ROText =>
-font => $TK{font},
-width => 80,
-height => 35,
-scrollbars => 'osoe',
)->pack(
-fill => 'both',
-expand => 'y',
);

$TK{out}->tag(configure => out => -foreground => 'black');
$TK{out}->tag(configure => err => -foreground => 'red');
$TK{out}->focus;

sub TIEHANDLE {
my $c = shift;
return bless \@_, $c;
}

sub PRINT {
my $s = shift;
my ($o, $t, $h) = @$s;

my $txt = do {
no warnings 'uninitialized';
(join $,, @_) . $\
};
openhandle $h and print $h $txt;
$o->insert(end => $txt, $t);
$o->see('end');
$o->update;
}

tie *STDOUT, __PACKAGE__, $TK{out}, 'out';
open my $OERR, '>&', \*STDERR;
tie *STDERR, __PACKAGE__, $TK{out}, 'err', $OERR;

sub Run (&$) {
my $sub = shift;
$TK{mw}->configure(-title => shift);
$TK{mw}->after(0, $sub);
Tk::MainLoop;
}

sub Dialog {
my $ans = $TK{mw}->Dialog(@_)->Show();
$TK{mw}->update;
return $ans;
}

sub Update {
$TK{mw}->update;
}

sub Tk::Error {
my ($mw, $err) = @_;
print STDERR $err;
}

1;
 
M

Mumia W.

Hi,

I am right now learning about Perl/TK and have a basic question
regarding subroutines and callbacks.

I was wondering how can I have the subroutine output to display in the
MainWindow if the subroutine is called using a button widget from the
MainWindow.

Here is the code that I wrote to test my above question.

#!/usr/bin/perl

use strict;
use Tk;

my $mw = MainWindow->new;
$mw->title("Demo Program");
$mw->Button(-text => "Test",
-command => sub{test()})->pack;
$mw->Button(-text => "Exit",
-command => sub{exit})->pack;
MainLoop;

sub test {
print "We have reached the subroutine part \n";
}

subroutine part" to display in the MainWindow when I press the "test"
button.

When I press the "Test" button the result is getting displayed on the
command line and not on the MainWindow.

Thanks,
doni

Create a label or something else to display the text and store the
reference to it. When you need to display something in that label,
change its text:

use strict;
use Tk;

my $mw = MainWindow->new;
$mw->title("Demo Program");
$mw->Button(-text => "Test",
-command => sub{testfunc()})->pack;
my $lbl = $mw->Label(-text => '')->pack;
$mw->Button(-text => "Exit",
-command => sub{exit})->pack;
MainLoop();

sub testfunc {
my $msg = $lbl->cget('-text');
$lbl->configure(-text => $msg . "We have reached the subroutine
part.\n");
}


__HTH__
 
B

Ben Morrow

Quoth Michele Dondi said:
Why don't you release it.

I've been half thinking about releasing it, but that means writing
tests/writing documentation/testing it cross-platform/etc. and I don't
really have time right now :).
It's cool, and certainly useful. Are you a
PerlMonks user too? If so, then you may also post it in the snippets
or code sections. If not, may I do so?

No, I'm not; and yes, of course you may :). Could you stick a

Copyright 2007 Ben Morrow

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.5
or, at your option, any later version of Perl 5 you may have
available.

section at the bottom? (I should really have done so before posting...)

Ben
 
B

Ben Morrow

Quoth Michele Dondi said:
AFAIK (not much, really) the latter two are not necessary. (But I
checked and it seems like it's actually so.)

They aren't strictly necessary: when you create a Button Tk will
autoload Tk::Button for you. But unfortunately it gives a warning, which
would be *very* confusing for users (or, at least, for *my* users :) ).

Ben
 
C

Ch Lamprecht

Ben said:
They aren't strictly necessary: when you create a Button Tk will
autoload Tk::Button for you. But unfortunately it gives a warning, which
would be *very* confusing for users (or, at least, for *my* users :) ).

With Tk-804 this should not be the case (not with Label and Button):

use strict;
use warnings;

use Tk;
my $mw = MainWindow->new( );

$mw->$_()->pack for qw/Label Button Entry Text/;
print "but:\n";
$mw->ROText()->pack;
MainLoop;

Christoph
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top