Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

Re: Refreshing text without flicker with AddLabel using Win32::GUI

by bmann (Priest)
on Dec 02, 2006 at 08:00 UTC ( #587372=note: print w/replies, xml ) Need Help??

in reply to Refreshing text without flicker with AddLabel using Win32::GUI

Hi Popcorn Dave,

Two things:

First, the sample code adds a label for each timer event rather than updating the existing label. If you watch memory usage as the test runs, it climbs gradually at each timer event.

Assign the original label to a variable when it is created. Then in redraw_Timer, instead of AddLabel just update $label->Text. This was enough to get rid of the flicker on my system.

This also solves the problem with the extra characters, since it redraws the label text every time.

use strict; use Win32::GUI(); my $interval = 100; my $main = Win32::GUI::Window->new( -name => 'Main', -width => 150, -height => 100, -onTimer => \&redraw_Timer, ); $main->AddTimer( "redraw_Timer", $interval); # add the following line my $label = $main->AddLabel( -text => scalar localtime ); $main->Show(); Win32::GUI::Dialog(); sub Main_Terminate { -1; } sub redraw_Timer{ my $temp = localtime; # replace the following line # return $main->AddLabel(-text => $temp); $label->Text( $temp ); }

Second, there is a noflicker option to Win32::GUI::Window->new, which for some reason defaults to 0.

Replies are listed 'Best First'.
Re^2: Refreshing text without flicker with AddLabel using Win32::GUI
by ikegami (Pope) on Dec 02, 2006 at 09:43 UTC

    Second, there is a noflicker option to Win32::GUI::Window->new, which for some reason defaults to 0.

    I was curious, so I investigated.

    When this option is off, window updates are performed as follows:

    • The part of the window that needs to be redrawn (or more) is redrawn.

    When this option is on, window updates are performed as follows:

    • A canvas (Device Context) is created.
    • A bitmap is allocated for the canvas.
    • The bitmap is initialized to the background colour.
    • The whole window (and child windows) is painted onto this canvas.
    • The bitmap is copied over the window's bitmap.
    • The bitmap is deallocated.
    • The canvas is deallocated.

    Think of it as buffering the output so that all the changes to the window's pixels occurs as close to instantly as possible.

    The latter takes longer to update the window, uses more resources and is probably rarely needed.

Re^2: Refreshing text without flicker with AddLabel using Win32::GUI
by Popcorn Dave (Abbot) on Dec 07, 2006 at 05:03 UTC
    Thanks very much for your reply! You've helped me get leaps and bounds beyond where I was before.

    I've finally had a few moments to try to play with what you suggested, and so naturally I'm stuck again. :)

    From what you described, I need to pre-define my labels so that I can just refresh the text that is being assigned to them. So far, good. Since this is a stock quote app that I'm writing, I've got a list of stocks I read out of a config file and save to a hash.

    My thought was to do something along the lines of:

    my %stocks = (^DJI =>{sec_label => $main->AddLabel( stuff...), current_label => #current price of stock, arrow_label => #direction of stock, change_label => #price change, pctchg_label => #percent change} )

    and I'm building this dynamically since I may add or delete stocks at any time and that's working out perfectly.

    What I'm getting stuck on is how to put parameters in the

    $stocks{$key}{arrow_label}->Text( $var );
    part where I'm just updating the text. In the arrow_label part of the hash, I want to be able to change the color to either red or green depending if a stock is going down or up respectively. Is there even a way to do that or am I stuck with just text?

    Revolution. Today, 3 O'Clock. Meet behind the monkey bars.
      Once the label is created, Win32::GUI doesn't expose a method to let you change the color. You might be able to use a custom Hook method to override painting the label.

      An alternative would be to create two labels, one red and one green. Make them identical in size and location in the window. Update the green one when the stock goes up, update the red one if the stock goes down.

        That's a great idea! I was thinking I could perhaps "destroy" the label and recreate it every time but that seemed a bit much to have to do. Since that label is the same size, overwriting it should be okay.


        Worked like a charm!

        Surprisingly enough, it doesn't seem to complain that you've got two labels in the same place, and will actually update depending on which one you choose.

        use strict; use Win32::GUI; use constant COLOR => '#F4F2E8'; my ($redraw, $count); $count = 0; my $main = Win32::GUI::Window->new( -name => 'Main', -text => 'Redraw Test', -width => 200, -height => 100, -background => COLOR, -onTimer => \&redraw, ); my $arrow_font = Win32::GUI::Font->new( -name => "Wingdings", -size => 28, -bold => 1, ); $main->AddTimer( "redraw", 500 ); my $uparrow = $main->AddLabel( -text => ' ', -left => 55, -font => $arrow_font, -foreground => [255,0,0], -background => COLOR, -top => 10, ); my $dnarrow = $main->AddLabel( -text => ' ', -left => 55, -font => $arrow_font, -foreground => [0,255,0], -background => COLOR, -top => 10, ); $main->Show(); Win32::GUI::Dialog(); sub Main_Terminate { -1; } sub redraw{ $count++; if ($count%2){ $dnarrow->Text(chr(233)); } else {$uparrow->Text(chr(234));} }

        The only thing that I found didn't work is to put '' in the text for the initial label. Once I changed that to ' ' all worked just fine.

        Thanks again for the idea!

        Revolution. Today, 3 O'Clock. Meet behind the monkey bars.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://587372]
[davido]: And remember; time is hard. :) As soon as you think, I've got this, you'll discover that time is harder than that. :)
[1nickt]: TCLion are you parsing the dates with DateTime or another tool?
[1nickt]: I note DateTime::Format:: Flexible, announced immediately below this box in the CPAN feed
[Corion]: 1nickt: That one sounds sensible as it will tell you when it found an error
[1nickt]: Throws on error, I believe
[1nickt]: But should handle month as number or word

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (14)
As of 2017-03-23 14:45 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (287 votes). Check out past polls.