Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Tk with Thread

9 views
Skip to first unread message

Slickuser

unread,
May 14, 2008, 7:57:37 PM5/14/08
to
I am currently using perl, v5.8.8 built for MSWin32-x86-multi-thread.

I have a Button on my GUI, when I pressed the button. It will parse
some file.
The parsing will run but my GUI will freeze. Once it's done parsing, I
can control my GUI again.

Is there a way to use Thread so my parsing is running and I can still
use my GUI?

I was looking at http://visitorflow.com/perl/lib/Thread.html

But it doesn't work for me. I also try 'threads' as well.

Any help?

Ben Morrow

unread,
May 14, 2008, 9:19:03 PM5/14/08
to

Quoth Slickuser <slick...@gmail.com>:

> I am currently using perl, v5.8.8 built for MSWin32-x86-multi-thread.
>
> I have a Button on my GUI, when I pressed the button. It will parse
> some file.
> The parsing will run but my GUI will freeze. Once it's done parsing, I
> can control my GUI again.

A straightforward way around this is to call $mainwindow->update
periodically during the processing. This can, however, be a little
tricky to arrange, depending on what the parsing consists of.

> Is there a way to use Thread so my parsing is running and I can still
> use my GUI?

Don't use Thread. It was part of the old 5005threads model that came
with 5.5; in 5.8 it is just a pass-through for threads.

It's best to read the documentation that comes with your version of
perl. That page appears to belong with 5.6.0: a lot has changed since
then, particularly wrt threads.

> But it doesn't work for me. I also try 'threads' as well.

'Doesn't work' is not a helpful problem description. Please reduce your
program to a minimal example (preferably just a Tk window with a single
button, and a sub that calls something like 'sleep 500' to simulate the
parsing) and post it. Also describe what it is doing that you don't
expect.

Tk will work in multithreaded programs, but be sure to only access the
Tk objects from one thread. Tk itself isn't threadsafe.

Ben

--
And if you wanna make sense / Whatcha looking at me for? (Fiona Apple)
* b...@morrow.me.uk *

zentara

unread,
May 15, 2008, 9:27:58 AM5/15/08
to


Here is a general purpose example. It creates threads before any
Tk is called, to be thread-safe. It creates a pool of 3 reusable
worker-threads, but you can cut down the complexity by using
just onw thread.

http://perlmonks.org?node_id=401819


You can also try the Tk::ExecuteCommand module.

#!/usr/bin/perl -w
use Tk;
use Tk::ExecuteCommand;
use Tk::widgets qw/LabEntry/;
use strict;

my $mw = MainWindow->new;

my $ec = $mw->ExecuteCommand(
-command => '',
-entryWidth => 50,
-height => 10,
-label => '',
-text => 'Execute',
)->pack;
$ec->configure(-command => 'date; sleep 10; date');


my $button = $mw->Button(-text =>'Do_it',
-background =>'hotpink',
-command => sub{ $ec->execute_command },
)->pack;

MainLoop;
__END__


--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html

Slickuser

unread,
May 19, 2008, 7:22:08 PM5/19/08
to
So I should used threads and not Thread?

Also, I look at fork. Will this help me?

Thanks.

On May 14, 6:19 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> QuothSlickuser<slick.us...@gmail.com>:


>
> > I am currently using perl, v5.8.8 built for MSWin32-x86-multi-thread.
>
> > I have a Button on my GUI, when I pressed the button. It will parse
> > some file.
> > The parsing will run but my GUI will freeze. Once it's done parsing, I
> > can control my GUI again.
>
> A straightforward way around this is to call $mainwindow->update
> periodically during the processing. This can, however, be a little
> tricky to arrange, depending on what the parsing consists of.
>
> > Is there a way to use Thread so my parsing is running and I can still
> > use my GUI?
>
> Don't use Thread. It was part of the old 5005threads model that came
> with 5.5; in 5.8 it is just a pass-through for threads.
>

> > I was looking athttp://visitorflow.com/perl/lib/Thread.html


>
> It's best to read the documentation that comes with your version of
> perl. That page appears to belong with 5.6.0: a lot has changed since
> then, particularly wrt threads.
>
> > But it doesn't work for me. I also try 'threads' as well.
>
> 'Doesn't work' is not a helpful problem description. Please reduce your

> program to a minimal example (preferably just aTkwindow with a single


> button, and a sub that calls something like 'sleep 500' to simulate the
> parsing) and post it. Also describe what it is doing that you don't
> expect.
>

> Tkwill work in multithreaded programs, but be sure to only access theTkobjects from one thread.Tkitself isn't threadsafe.

Joost Diepenmaat

unread,
May 19, 2008, 7:25:48 PM5/19/08
to
Slickuser <slick...@gmail.com> writes:

> So I should used threads and not Thread?

Yes. And make sure you've got a recent version of perl.

> Also, I look at fork. Will this help me?

Maybe. You could also check out Tk::fileevent, perlopentut, and
IO::AIO on CPAN.

--
Joost Diepenmaat | blog: http://joost.zeekat.nl/ | work: http://zeekat.nl/

Slickuser

unread,
May 19, 2008, 7:57:14 PM5/19/08
to
Here is a sample code:

use strict;
use warnings;
use Tk;
use threads;

my $mainWindow = MainWindow->new;
my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7, -
scrollbars=>"ose", -wrap=>"word")->pack();

$mainWindow->Button(-foreground=>"blue", -text=>"Click", -command=>
\&excecute)->pack();

MainLoop;

sub excecute
{
my $thr = threads->new(\&click);
$thr->join;
$thr->detach;
}

sub click
{

open(FILE,"C:/file.txt") or die "can't open\n";
while(<FILE>)
{
my $line = $_;

$textBox->insert('end', "$line\n");
$textBox->see('end');
$textBox->update;
}
return;
}


I got the following error:
Tk::Error: Can't call method "WidgetMethod" on an undefined value at
C:/Perl/sit
e/lib/Tk.pm line 252, <FILE> line 5568.
[set,{}]
(vertical scrolling command executed by text)
Tk::Error: Can't call method "WidgetMethod" on an undefined value at
C:/Perl/sit
e/lib/Tk.pm line 252, <FILE> line 5807.
[set,{}]
(vertical scrolling command executed by text)
Terminating on signal SIGINT(2)


On May 19, 4:25 pm, Joost Diepenmaat <jo...@zeekat.nl> wrote:


> Slickuser<slick.us...@gmail.com> writes:
> > So I should used threads and not Thread?
>
> Yes. And make sure you've got a recent version of perl.
>
> > Also, I look at fork. Will this help me?
>

> Maybe. You could also check outTk::fileevent, perlopentut, and

Joost Diepenmaat

unread,
May 19, 2008, 8:03:23 PM5/19/08
to
Slickuser <slick...@gmail.com> writes:

> Here is a sample code:
>
> use strict;
> use warnings;
> use Tk;
> use threads;
>
> my $mainWindow = MainWindow->new;
> my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7, -
> scrollbars=>"ose", -wrap=>"word")->pack();
>
> $mainWindow->Button(-foreground=>"blue", -text=>"Click", -command=>
> \&excecute)->pack();
>
> MainLoop;
>
> sub excecute
> {
> my $thr = threads->new(\&click);
> $thr->join;
> $thr->detach;
> }
>
> sub click
> {
>
> open(FILE,"C:/file.txt") or die "can't open\n";
> while(<FILE>)
> {
> my $line = $_;
>
> $textBox->insert('end', "$line\n");
> $textBox->see('end');
> $textBox->update;
> }
> return;
> }

You shouldn't expect to be able to close over or otherwise refer to
objects in multiple threads, unless the docs for those objects
explictely say you can.

IOW: perl threads do not work like C/Java type low-level threads, and
mostly you want to minimize the communication between them.

Slickuser

unread,
May 19, 2008, 8:16:44 PM5/19/08
to
Here is the update code with the same error.

I would like to be able to move my Tk window when a button is press.
Currently, it's freeze until it's done parsing.

use strict;
use warnings;
use Tk;
use threads;

my $mainWindow = MainWindow->new;
my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7, -
scrollbars=>"ose", -wrap=>"word")->pack();

$mainWindow->Button(-foreground=>"blue", -text=>"Click", -command=>
\&excecute)->pack();

MainLoop;

sub excecute
{
my $thr = threads->new(\&click);
$thr->join;

#$thr->detach;
}

sub click
{
my @data;

open(FILE,"C:/file.txt") or die "can't open\n";
while(<FILE>)
{
my $line = $_;

push(@data,$line);
}
close(FILE);

$textBox->insert('end', "@data\n");


$textBox->see('end');
$textBox->update;

return;

Ben Morrow

unread,
May 19, 2008, 8:12:19 PM5/19/08
to
[please quote properly]

Quoth Slickuser <slick...@gmail.com>:


> So I should used threads and not Thread?

Yes.

> Also, I look at fork. Will this help me?
>

> On May 14, 6:19 pm, Ben Morrow <b...@morrow.me.uk> wrote:
> > QuothSlickuser<slick.us...@gmail.com>:
> >
> > > I am currently using perl, v5.8.8 built for MSWin32-x86-multi-thread.

Since you are on Win32, no. Win32 doesn't provide fork, and perl
emulates it using threads. If you aren't trying to write code which is
portable to Unix, it's probably better to use threads directly.

Ben

--
It will be seen that the Erwhonians are a meek and long-suffering people,
easily led by the nose, and quick to offer up common sense at the shrine of
logic, when a philosopher convinces them that their institutions are not based
on the strictest morality. [Samuel Butler, paraphrased] b...@morrow.me.uk

Ben Morrow

unread,
May 20, 2008, 6:38:13 AM5/20/08
to

Quoth Joost Diepenmaat <jo...@zeekat.nl>:

> Slickuser <slick...@gmail.com> writes:
>
> > Here is a sample code:
> >
> > use strict;
> > use warnings;
> > use Tk;
> > use threads;
> >
> > my $mainWindow = MainWindow->new;
> > my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7, -
> > scrollbars=>"ose", -wrap=>"word")->pack();
> >
<snip>

> > sub excecute
> > {
> > my $thr = threads->new(\&click);
> > $thr->join;
> > $thr->detach;
> > }
> >
> > sub click
> > {
> >
<snip>

> > $textBox->insert('end', "$line\n");
<snip>

>
> You shouldn't expect to be able to close over or otherwise refer to
> objects in multiple threads, unless the docs for those objects
> explictely say you can.

More importantly, in this case, you mustn't access Tk (at all) from more
than one thread, since it isn't threadsafe.

Ben

--
For the last month, a large number of PSNs in the Arpa[Inter-]net have been
reporting symptoms of congestion ... These reports have been accompanied by an
increasing number of user complaints ... As of June,... the Arpanet contained
47 nodes and 63 links. [ftp://rtfm.mit.edu/pub/arpaprob.txt] * b...@morrow.me.uk

Tad J McClellan

unread,
May 20, 2008, 7:50:50 AM5/20/08
to
Slickuser <slick...@gmail.com> wrote:


> while(<FILE>)
> {
> my $line = $_;
> push(@data,$line);
> }


You can replace all of that code with:

my @data = <FILE>;


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"

zentara

unread,
May 20, 2008, 8:40:29 AM5/20/08
to
On Mon, 19 May 2008 17:16:44 -0700 (PDT), Slickuser
<slick...@gmail.com> wrote:

>Here is the update code with the same error.
>
>I would like to be able to move my Tk window when a button is press.
>Currently, it's freeze until it's done parsing.

I get all sorts of errors regarding thread corruption, since you
created your thread after Tk is invoked, and you try to access the
Tk text widget from the thread. Gtk2 will allow you to do that, but Tk
won't. Even Gtk2 needs some precautions.

This is a basic Tk thread script, to show you the ropes.
You can search groups.google.com for "perl Tk threads"
and find all of the many examples that have been posted previously.

#!/usr/bin/perl


use strict;
use warnings;
use Tk;
use threads;

use threads::shared;

my $go:shared = 0;
my $die:shared = 0;
my $count:shared = 0;

# make thread before any Tk is called,
# usually a sleeping thread
my $thr = threads->new(\&new_thread);

my $mainWindow = MainWindow->new;
my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7,

-scrollbars=>"ose", -wrap=>"word")->pack();

$mainWindow->Button(-foreground=>"blue", -text=>"Click",
-command=>\&excecute)->pack();

$mainWindow->Button(-foreground=>"red", -text=>"Stop",
-command=>sub{ $go=0 })->pack();

$mainWindow->Button(-foreground=>"black", -text=>"exit",
-command=>sub{ $die=1;
$thr->join;
exit;
})->pack();

# you must actively read the shared variables with a timer
# filehandles can be shared thru the fileno,
# search groups.google for examples
my $repeater = $mainWindow->repeat(1000,sub{
if($go){
$textBox->insert('end', "$count\n");


$textBox->see('end');
$textBox->update;
}

});


MainLoop;

sub new_thread{

while(1){
if($die){return} #thread can only be joined after it returns
if( $go == 1){
if($die){return}

$count++;

}else{ select undef,undef,undef,.1} #sleep awhile
}
}

sub excecute { $go = 1 }
__END__

Those are the basics, but search groups.google.com, because
we have answered these questions many times before, with code examples.

zentara

Slickuser

unread,
Jun 6, 2008, 6:03:28 PM6/6/08
to
Can you explain this line of the code about the sleep and what is .1
for?

select undef,undef,undef,.1; #sleep awhile

Thx.

On May 20, 5:40 am, zentara <zent...@highstream.net> wrote:
> On Mon, 19 May 2008 17:16:44 -0700 (PDT),Slickuser
>

J. Gleixner

unread,
Jun 6, 2008, 6:16:50 PM6/6/08
to
Slickuser wrote:
> Can you explain this line of the code about the sleep and what is .1
> for?
>
> select undef,undef,undef,.1; #sleep awhile

You may look it up on your own:

perldoc -f select

select RBITS,WBITS,EBITS,TIMEOUT
...
You can effect a sleep of 250 milliseconds this way:

select(undef, undef, undef, 0.25);

Slickuser

unread,
Jun 8, 2008, 5:58:30 PM6/8/08
to
I try to use Excel OLE but it crashes when I click exit.
Is there a way to work around?

use strict;
use warnings;
#use Win32::OLE;
#use Win32::OLE::Const 'Microsoft Excel';
use Tk;
use Tk::Balloon;


use threads;
use threads::shared;

my $run:shared = 0;
my $exit:shared = 0;


my $count:shared = 0;

my $thr = threads->new(\&new_thread);

my $mainWindow = MainWindow->new;
my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7,

-scrollbars=>"ose", -wrap=>"word")->grid();

$mainWindow->Button(-foreground=>"blue", -text=>"Click",

-command=>\&excecute)->grid();

my $stopBut = $mainWindow->Button(-foreground=>"red", -text=>"Stop",
-command=>sub{ $run=0; })->grid();


$mainWindow->Button(-foreground=>"black", -text=>"exit",

-command=>sub{ $exit=1;
$thr->join;
exit;
})->grid();

my $repeater = $mainWindow->repeat(1000,sub{

if($run){


$textBox->insert('end', "$count\n");
$textBox->see('end');
$textBox->update;

$stopBut->configure(-state=> "disabled");
}
});

MainLoop;

sub new_thread{

while(1)
{
if($exit){ return; } #thread can only be joined after it
returns
if($run)
{
if($exit){return;}
&test;

}
else
{
## Sleep for 1 miliseconds
select(undef,undef,undef,.1);
}
}

}
sub test{
$count++;
}


sub excecute { $run = 1 }

Slickuser

unread,
Jun 8, 2008, 7:00:45 PM6/8/08
to
I want my script to have GUI, click a button, it will parse some raw
data, update the progress on the gui, use excel ole to output the
final result.

zentara

unread,
Jun 9, 2008, 10:19:35 AM6/9/08
to
On Sun, 8 Jun 2008 14:58:30 -0700 (PDT), Slickuser
<slick...@gmail.com> wrote:

>I try to use Excel OLE but it crashes when I click exit.
>Is there a way to work around?
>
>use strict;
>use warnings;
>#use Win32::OLE;
>#use Win32::OLE::Const 'Microsoft Excel';
>use Tk;
>use Tk::Balloon;
>use threads;
>use threads::shared;
>
>my $run:shared = 0;
>my $exit:shared = 0;
>my $count:shared = 0;
>
>
> my $thr = threads->new(\&new_thread);
>

I don't use windows, but your code runs fine for me (without the OLE
modules).

It's possible that Win32 OLE is not threadsafe, and if a thread dies(
crashes) it will take the main thread too.

As a guess, you might want to move the OLE modules use declarations down
into the thread code block, and see if that works.

zentara

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

http://zentara.net/CandyGram_for_Mongo.html

Slickuser

unread,
Jun 9, 2008, 11:22:12 AM6/9/08
to
When I move the use OLE to where I want to use it. Here's the error I
get.

Free to wrong pool 2db6e00 not 222dc8 during global destruction.

use strict;
use warnings;
use Tk;

use threads;
use threads::shared;

my $run:shared = 0;
my $exit:shared = 0;
my $count:shared = 0;


my $thr = threads->new(\&new_thread);

my $mainWindow = MainWindow->new;


my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7,

-scrollbars=>"ose", -wrap=>"word")->pack();

$mainWindow->Button(-foreground=>"blue", -text=>"Click",

-command=>\&excecute)->pack();

my $stopBut = $mainWindow->Button(-foreground=>"red", -text=>"Stop",

-command=>sub{ $run=0; })->pack();


$mainWindow->Button(-foreground=>"black", -text=>"exit",
-command=>sub{ $exit=1;
$thr->join;
exit;

})->pack();

my $repeater = $mainWindow->repeat(1000,sub{
if($run){
$textBox->insert('end', "$count\n");
$textBox->see('end');
$textBox->update;

#$stopBut->configure(-state=> "disabled");
}
});


MainLoop;

sub new_thread{

while(1)
{
if($exit){ return; } #thread can only be joined after it
returns
if($run)
{
if($exit){return;}
&test;

}
else
{
## Sleep for 1 miliseconds
select(undef,undef,undef,.1);
}
}

}
sub test{
$count++;
#$::stopBut->configure(-state=> "disabled");
}


sub excecute {

$run = 1 ;

use Win32::OLE;

Slickuser

unread,
Jun 9, 2008, 7:18:07 PM6/9/08
to
Here is what I want to achieve:
Have the GUI up, use thread to process the data (read from file) and
Excel OLE to output the data.
I don't want my GUI to freeze up when it's running.
I got the script going but I got couple of errors below.

Any help would be great. Thanks a lot.

Attempt to free non-existent shared string '_TK_RESULT_', Perl
interpreter: 0x2e
e14dc at C:\Documents and Settings\slickuser\Desktop\thread3.pl line
22.
Tk::Error: Can't call method "Call" on an undefined value at C:/Perl/
site/lib/Tk
/After.pm line 89.
[once,[{},after#7,idle,once,[ConfigChanged,{},{}]]]
("after" script)
Tk::Error: Can't call method "Call" on an undefined value at C:/Perl/
site/lib/Tk
/After.pm line 89.
[once,[{},after#8,idle,once,[ConfigChanged,{},{}]]]
("after" script)
Attempt to free non-existent shared string 'Value', Perl interpreter:
0x22485c a
t (eval 9) line 1.
Free to wrong pool 222da8 not 2ed3ec8 at (eval 9) line 1.


Here is my code:

use strict;
use warnings;
use Tk;
use threads;

my $thr;

my $mainWindow = MainWindow->new;
my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7,
-scrollbars=>"ose", -wrap=>"word")->pack();

my $goBut = $mainWindow->Button(-foreground=>"blue", -text=>"Click",
-command=>sub { $thr = threads->new(\&excecute) } )-
>pack();

my $stopBut = $mainWindow->Button(-foreground=>"red", -text=>"Exit",
-command=>sub{ if(defined($thr)){ $thr->detach; }
exit; })->pack();

MainLoop;


sub excecute
{
$goBut->configure(-state=>"disabled");
$textBox->configure(-state=>"normal");
open(FILE,"C:/file.txt") or die "Can't open file.\n";
while(<FILE>)
{
my $message = $_;
$textBox->insert('end', $message);
}
close(FILE);

$textBox->configure(-state=>"disabled");
$textBox->see('end');

use Win32::OLE;


use Win32::OLE::Const 'Microsoft Excel';

my ($Excel,$Workbook,$fileOutput,$CurrentSheet,$Range);
$fileOutput = "C:/test.xls";

$Excel = Win32::OLE->new('Excel.Application', 'Quit') || die "Can't
create Excel object. \n";
$Excel->{'Visible'} = 1; #0 is hidden, 1 is visible
$Excel->{DisplayAlerts} = 0; #0 is hide alerts
$Excel->{SheetsInNewWorkbook} = 1;
$Workbook = $Excel->Workbooks->Add();

$Workbook->SaveAs($fileOutput) or die "Can't save Excel.\n";
$CurrentSheet = $Workbook->Worksheets(1);
$CurrentSheet->Select;

for (my $i=1; $i<=65356; $i++)
{
$Range = $CurrentSheet->Range("A$i");
$Range->{Value} = $i;
sleep(0.01);
}

$Workbook->Save();
$Workbook->Close();
$Excel->Quit();
Win32::OLE->FreeUnusedLibraries();
$goBut->configure(-state=>"normal");

return;
}

zentara

unread,
Jun 10, 2008, 9:20:09 AM6/10/08
to
On Mon, 9 Jun 2008 08:22:12 -0700 (PDT), Slickuser
<slick...@gmail.com> wrote:

>When I move the use OLE to where I want to use it. Here's the error I
>get.
>
>Free to wrong pool 2db6e00 not 222dc8 during global destruction.

That is definitely an error caused by threads getting confused.
Try putting your

use Win32::OLE;
use Win32::OLE::Const 'Microsoft Excel';

in the new_thread sub. The other subs are part of the main code.

Also, try to make new_thread self-contained, don't use a separate
&test. Additionally, you are trying to access the Tk widget from thread
code in &test..... this cannot be done.

You cannot try to access Tk widgets in main from the thread, use a timer
and shared variables instead.

--

zentara

unread,
Jun 10, 2008, 9:20:09 AM6/10/08
to
On Mon, 9 Jun 2008 16:18:07 -0700 (PDT), Slickuser
<slick...@gmail.com> wrote:

>Here is what I want to achieve:
>Have the GUI up, use thread to process the data (read from file) and
>Excel OLE to output the data.
>I don't want my GUI to freeze up when it's running.
>I got the script going but I got couple of errors below.
>
>Any help would be great. Thanks a lot.

Go back and read the advice from previous threads. You must create
any thread before any Tk is called. You are trying to launch a thread
from a Tk button callback...... it won't work.

If you insist on using these types of designs, you will need to switch
to Perl/Gtk2, which allows some of these things, with certain
precautions.

Search groups.google.com for many examples of "Perl Tk thread" and
"perl Gtk2 thread".

--

Ben Morrow

unread,
Jun 10, 2008, 10:55:26 AM6/10/08
to

Quoth zentara <zen...@highstream.net>:

> On Mon, 9 Jun 2008 08:22:12 -0700 (PDT), Slickuser
> <slick...@gmail.com> wrote:
>
> >When I move the use OLE to where I want to use it. Here's the error I
> >get.
> >
> >Free to wrong pool 2db6e00 not 222dc8 during global destruction.
>
> That is definitely an error caused by threads getting confused.
> Try putting your
> use Win32::OLE;
> use Win32::OLE::Const 'Microsoft Excel';
>
> in the new_thread sub. The other subs are part of the main code.

This won't change anything. Use statements are executed at compile-time,
before any threads have been created.

If you *really* need to use a module in a particular thread, you need to
'require' it and call ->import manually. This is almost certainly not
necessary in this case, though.

> Also, try to make new_thread self-contained, don't use a separate
> &test. Additionally, you are trying to access the Tk widget from thread
> code in &test..... this cannot be done.

This is much more likely to be the problem.

Ben

--
Like all men in Babylon I have been a proconsul; like all, a slave ... During
one lunar year, I have been declared invisible; I shrieked and was not heard,
I stole my bread and was not decapitated.
~ b...@morrow.me.uk ~ Jorge Luis Borges, 'The Babylon Lottery'

Slickuser

unread,
Jun 10, 2008, 4:30:58 PM6/10/08
to
How would I go fixing my code below to make it work?

I am just frustrate that I can't get it to work and not any example
toward to this issue. Thanks.

use strict;
use warnings;
use Tk;
use threads;

#use Win32::OLE;
#use Win32::OLE::Const 'Microsoft Excel';

my $thr;

my $mainWindow = MainWindow->new;
my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7,
-scrollbars=>"ose", -wrap=>"word")->pack();

my $goBut = $mainWindow->Button(-foreground=>"blue", -text=>"Click",
-command=>sub {
$thr = threads->new(\&excecute);
#&excecute;
} )->pack();

my $stopBut = $mainWindow->Button(-foreground=>"red", -text=>"Exit",


-command=>sub{
if(defined($thr)){ $thr->detach; }
exit;
})->pack();

MainLoop;


sub excecute
{
$goBut->configure(-state=>"disabled");
$textBox->configure(-state=>"normal");

open(FILE,"C:/file.txt") or die "Can't open file.\n";
while(<FILE>)
{


my $message = $_;
$textBox->insert('end', $message);
}
close(FILE);

$textBox->configure(-state=>"disabled");
$textBox->see('end');

use Win32::OLE;


use Win32::OLE::Const 'Microsoft Excel';

my ($Excel,$Workbook,$fileOutput,$CurrentSheet,$Range);
$fileOutput = "C:/test.xls";

$Excel = Win32::OLE->new('Excel.Application', 'Quit') || die "Can't
create Excel object. \n";
$Excel->{'Visible'} = 1; #0 is hidden, 1 is visible
$Excel->{DisplayAlerts} = 0; #0 is hide alerts
$Excel->{SheetsInNewWorkbook} = 1;
$Workbook = $Excel->Workbooks->Add();

$Workbook->SaveAs($fileOutput) or die "Can't save Excel.\n";
$CurrentSheet = $Workbook->Worksheets(1);
$CurrentSheet->Select;

for (my $i=1; $i<=2000; $i++)


{
$Range = $CurrentSheet->Range("A$i");
$Range->{Value} = $i;
sleep(0.01);
}

$Workbook->Save();
$Workbook->Close();
$Excel->Quit();
Win32::OLE->FreeUnusedLibraries();
$goBut->configure(-state=>"normal");
return;
}

On Jun 10, 7:55 am, Ben Morrow <b...@morrow.me.uk> wrote:
> Quoth zentara <zent...@highstream.net>:

zentara

unread,
Jun 11, 2008, 7:32:43 AM6/11/08
to
On Tue, 10 Jun 2008 13:30:58 -0700 (PDT), Slickuser
<slick...@gmail.com> wrote:

>How would I go fixing my code below to make it work?
>
>I am just frustrate that I can't get it to work and not any example
>toward to this issue. Thanks.

This dosn't use any win32 stuff, but shows how to do it. When you
add in your excel stuff, put the results in a shared variable, and read
it in the timer.

#!/usr/bin/perl


use strict;
use warnings;
use Tk;
use threads;

use threads::shared;

my $data:shared = '';
my $go_control:shared = 0;
my $die_control:shared = 0;

#create thread before any Tk
my $thr = threads->new(\&excecute);


my $mainWindow = MainWindow->new;

my $textBox = $mainWindow->Scrolled("Text", -width=>80, -height=>7,
-scrollbars=>"ose", -wrap=>"word")->pack();

my $goBut; # need to declare here so can be used in -command


$goBut = $mainWindow->Button(-foreground=>"blue", -text=>"Click",
-command=>sub {

$goBut->configure(-state=>"disabled");

$textBox->configure(-state=>"normal");
$go_control = 1; #start thread
} )->pack();

my $stopBut = $mainWindow->Button(-foreground=>"red", -text=>"Exit",

-command=>sub{ $die_control = 1;


$thr->join;
exit;
})->pack();

#use a timer to read the shared variable and deal with Tk stuff

my $repeater = $mainWindow->repeat(20,sub{

$textBox->insert('end',$data);
$textBox->see('end');


});


MainLoop;


sub excecute{

# require Win32::OLE;
# require Win32::OLE::Const 'Microsoft Excel';

while(1){

#wait for $go_control
if($go_control){
open(FILE,$0 ) or die "Can't open file.\n";
while(<FILE>){
if($die_control){return}
$data = $_;
}
close(FILE);
}else{ select(undef,undef,undef,.25); }# sleep until awakened
}

return;
}

__END__

zentara

0 new messages