Home > Archive > PerlTk > August 2004 > Am I Using a Canvas and Images Correctly?
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Am I Using a Canvas and Images Correctly?
|
|
| JohnTC 2004-08-09, 3:55 am |
| Thanks in advance for helping out a newbie. <smile>
Basically, I have a canvas of a certain size, and I'd like it to
display 120 images in a grid, with the images being refreshed every
second.
So I've created my main window and canvas. I've also a set of photo
objects from gif files in the following way:
$mw -> Photo('pine', -file => "icons/pine.gif");
To display the photos in the canvas, I'm doing this for each square in
the grid every second (using the repeat method on a button):
$id = $canvas->create( 'image', $gridx, $gridy, '-anchor' => 'nw',
'-image' => pine );
There is a display sub, called every second by the timer, that uses a
bunch of these $canvas->create statements to paint the various icons
in the proper squares of the grid.
The problem that I am running into, is that the program's display sub
is taking progressively longer to complete each new cycle. The
increase is very slow, but steady.
---
I'm thinking (dunno if I am right) that I must be creating a bunch of
new objects each time the display sub is called, not just merely
painting pixels to a canvas. The steadily mounting numbers of these
objects are increasing the amount of time it takes for Perl/Tk to do
it's thing.
I've tried collecting the IDs of every object created (as above) &
deleting them once the new images are displayed on the canvas like so:
$canvas->delete(objectIDhere);
This does not seem to affect matters.
---
Basically, I'd just like to push some pixels (well, gif pixels) to a
canvas once every second, on a continual basis, without creating a lot
of extra mess in memory. Is there a better way of doing this?
Many Thanks,
JohnTC
| |
| zentara 2004-08-09, 3:57 pm |
| On 9 Aug 2004 00:28:11 -0700, john_google@wmuse.com (JohnTC) wrote:
>Basically, I have a canvas of a certain size, and I'd like it to
>display 120 images in a grid, with the images being refreshed every
>second.
>
>So I've created my main window and canvas. I've also a set of photo
>objects from gif files in the following way:
>
>$mw -> Photo('pine', -file => "icons/pine.gif");
>
>To display the photos in the canvas, I'm doing this for each square in
>the grid every second (using the repeat method on a button):
>
>$id = $canvas->create( 'image', $gridx, $gridy, '-anchor' => 'nw',
>'-image' => pine );
>
>There is a display sub, called every second by the timer, that uses a
>bunch of these $canvas->create statements to paint the various icons
>in the proper squares of the grid.
>
>The problem that I am running into, is that the program's display sub
>is taking progressively longer to complete each new cycle. The
>increase is very slow, but steady.
>
>---
>
>I'm thinking (dunno if I am right) that I must be creating a bunch of
>new objects each time the display sub is called, not just merely
>painting pixels to a canvas. The steadily mounting numbers of these
>objects are increasing the amount of time it takes for Perl/Tk to do
>it's thing.
>
>I've tried collecting the IDs of every object created (as above) &
>deleting them once the new images are displayed on the canvas like so:
>
>$canvas->delete(objectIDhere);
>
>This does not seem to affect matters.
Yeah, you are running into a common problem with images and Tk, where
you get a memory increase due to stray objects laying around. The first
thing most people try is to destroy the image objects and then recreate
them, it dosn't work.
The general rule is this: Create your photo objects once, and store them
in a hash, and reuse them at every update.
So you would want to create 120 photo objects and store them, like
my %photos
for (1..120){ $photo{$_} = $mw->Photo(-file => "$_ . jpg");
}
Now you can reuse a photo object by blanking it, and reading a new
file into it. So in your update routine something like:
for(1..120){
$photo{$_}->blank;
$photo{$_}->read("$_-new.jpg");
}
I have a simple little memory leak monitor at
http://perlmonks.org?node_id=336856
It will pop up a little box in the upper left corner of your monitor,
and will display the memoery usage of the script, so you can monitor
where these "pseudo-leaks" occur.
--
I'm not really a human, but I play one on earth.
http://zentara.net/japh.html
| |
| Slaven Rezic 2004-08-10, 3:57 pm |
| john_google@wmuse.com (JohnTC) wrote in message news:<647b9871.0408082328.f057da5@posting.google.com>...
> Thanks in advance for helping out a newbie. <smile>
>
> Basically, I have a canvas of a certain size, and I'd like it to
> display 120 images in a grid, with the images being refreshed every
> second.
>
> So I've created my main window and canvas. I've also a set of photo
> objects from gif files in the following way:
>
> $mw -> Photo('pine', -file => "icons/pine.gif");
>
> To display the photos in the canvas, I'm doing this for each square in
> the grid every second (using the repeat method on a button):
>
> $id = $canvas->create( 'image', $gridx, $gridy, '-anchor' => 'nw',
> '-image' => pine );
>
> There is a display sub, called every second by the timer, that uses a
> bunch of these $canvas->create statements to paint the various icons
> in the proper squares of the grid.
>
> The problem that I am running into, is that the program's display sub
> is taking progressively longer to complete each new cycle. The
> increase is very slow, but steady.
>
> ---
>
> I'm thinking (dunno if I am right) that I must be creating a bunch of
> new objects each time the display sub is called, not just merely
> painting pixels to a canvas. The steadily mounting numbers of these
> objects are increasing the amount of time it takes for Perl/Tk to do
> it's thing.
>
> I've tried collecting the IDs of every object created (as above) &
> deleting them once the new images are displayed on the canvas like so:
>
> $canvas->delete(objectIDhere);
>
> This does not seem to affect matters.
>
> ---
>
> Basically, I'd just like to push some pixels (well, gif pixels) to a
> canvas once every second, on a continual basis, without creating a lot
> of extra mess in memory. Is there a better way of doing this?
>
You should also keep track of the created photos and delete them with
the delete() method:
$photo = $canvas->Phote(-file => ...);
...
$photo->delete;
Regards,
Slaven
| |
| JohnTC 2004-08-12, 3:58 am |
| > >
>
> You should also keep track of the created photos and delete them with
> the delete() method:
>
> $photo = $canvas->Phote(-file => ...);
> ...
> $photo->delete;
>
> Regards,
> Slaven
Many thanks, Slaven.
I did need to delete the photo objects, but it turned out that I was
not deleting all of my $canvas->create image objects. Proper
housecleaning works wonders.
JohnTC
|
|
|
|
|