Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Re^2: Perl tk gui hangs when large data thrown to it

by Anonymous Monk
on Oct 15, 2013 at 10:54 UTC ( #1058285=note: print w/ replies, xml ) Need Help??


in reply to Re: Perl tk gui hangs when large data thrown to it
in thread Perl tk gui hangs when large data thrown to it

can you give me any email address or the like so that I can send you some files otherwise the code is too huge to include here.


Comment on Re^2: Perl tk gui hangs when large data thrown to it
Re^3: Perl tk gui hangs when large data thrown to it
by BrowserUk (Pope) on Oct 15, 2013 at 11:23 UTC
    the code is too huge to include here.

    Simplify it. That is, make a simplified version of it for testing. Just the single widget that displays your changing data, the timer routine that processes inbound packets and the updateDisplay() routine. This would be invaluable to you for testing the maximum throughput you can expect of Tk and your tcp code.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Well, even the simplified version will be quite long. I have described the entire thing here, but may be it is not sufficient for you to guess.
      FYI, I am giving the update gui routine here, which is getting called from the server function as and when it has read some data from the socket.

      sub updateGui { my $self = shift; my $data = shift; my $hlist = $self->{jobTree}; my @cellInfo = split( /\s/, $data ); my $font = "{helvetica} -12 bold"; my $style1 = $self->{displaybaseObj}->getItemStyle( $hlist, 'text', -foreground => 'black', -anchor => 'nw', -background => "$cellInfo[2]", -font => $font ); my $num1 = int( rand(2) ) + 1; my $num2 = int( rand(2) ) + 0; my $subnode1 = $cellInfo[0] . "." . $num1; my $subnode2 = $cellInfo[0] . "." . $num1 . "." . "0" . "." . $num +2; $hlist->itemConfigure( $subnode1, 2, -text => "$cellInfo[1]", -style => $style1 ); $hlist->itemConfigure( $subnode2, 2, -text => "$cellInfo[1]", -style => $style1 ); }

      The $data to this routine is like "500 running green" i.e a gui row , some status of that and a colour separated by single space. $hlist is the Tree widget which just a bit extension of the built in HList.pm Tk module.

      Let me see , if I can post a very simplified version of it.

      I am just including a very very simplified code which is just one perl file only. Please change the repeat frequency to test it. The gui would show better performance if the repeat frequency is increased to 1sec , currently it is 1ms only.
      My requirement is :

      1. what is the reason for the gui to get hung when we are trying to change some 100 rows on it every 1 ms . Can not perl tk handle this ? is this a limitation ?

      2. is their any other mechanism to make it work, provided i will repeat it every 1 ms and would try to change 100 rows of it randomly.

      use Tk; use Tk::HList; use Time::HiRes qw/usleep/; my $mw = MainWindow->new(); my $hlistframe = $mw->Frame()->pack( -fill => 'both', -expand => 1 ); my $font = "{helvetica} -12 bold"; my $hl = $hlistframe->Scrolled( 'HList', -scrollbars => 'ose', -columns => 7, -header => 1, #-height => 10, -width => 50, -command => sub { print "test\n"; }, )->pack( -fill => 'both', -expand => 1 ); my $num = $hl->Label( -text => "Number", -anchor => 'w', -font => $fon +t ); $hl->headerCreate( 0, -itemtype => 'window', -widget => $num ); my $name = $hl->Label( -text => "ID", -anchor => 'w', -font => $font ) +; $hl->headerCreate( 1, -itemtype => 'window', -widget => $name ); my $DOB = $hl->Label( -text => "Job", -anchor => 'w', -font => $font ) +; $hl->headerCreate( 2, -itemtype => 'window', -widget => $DOB ); my $Address = $hl->Label( -text => "status", -anchor => 'w', -font => +$font ); $hl->headerCreate( 3, -itemtype => 'window', -widget => $Address ); my $style1 = $hl->ItemStyle( 'text', -selectforeground => 'black', -anchor => 'nw', -background => 'green', -font => $font ); my $style2 = $hl->ItemStyle( 'text', -selectforeground => 'black', -anchor => 'nw', -background => 'red', -font => $font ); my $style3 = $hl->ItemStyle( 'text', -selectforeground => 'black', -anchor => 'nw', -background => 'blue', -font => $font ); sub populate { my $path = 0; foreach my $entry ( 1 .. 100 ) { insertData( $path, $entry ); $path++; } } &populate(); sub insertData { my ( $path, $entry ) = @_; $hl->add($path); # print "path $path \n"; $hl->itemCreate( $path, 0, -text => "$path" ); # , -style => $ +style1); $hl->itemCreate( $path, 1, -text => "someid" ); # , -style => $ +style1); $hl->itemCreate( $path, 2, -text => "test" ); #, -style => $s +tyle1); $hl->itemCreate( $path, 3, -text => "running", -style => $style1 ) +; } $mw->repeat( 1, \&changeItem ); my $flag; sub changeItem { my %flag; foreach ( 1 .. 100 ) { my $randRow = int( rand(20) ); print "randRow $randRow \n"; if ( $flag{$randRow} ) { $hl->itemConfigure( $randRow, 3, -text => "pending", -style => $style2 ); $hl->itemConfigure( $randRow, 3, -text => "waiting", -style => $style2 ); $flag{$randRow} = 0; print "if flag ", $flag{$randRow}, "\n"; } else { print "else flag 0\n"; $hl->itemConfigure( $randRow, 3, -text => "finished", -style => $style3 ); $hl->itemConfigure( $randRow, 3, -text => "aborted", -style => $style3 ); $flag{$randRow} = 1; print "else flag ", $flag{$randRow}, " \n"; } #usleep(100); #sleep 2 ; } } MainLoop;

        I think you're just expecting too much. You cannot see an event that only lasts 1 millisecond so there's no point updating you display that quickly. If you data really is changing that quickly just cache it until the next screen update.

        I've changed the repeat to 20ms, removed the prints from changeitem and increased then rand row to 100, and your code works. But even 50 updates per second are too many, I'd try 10 or less, as you don't really need video rates.

        The bottom line is that your gui is not "hanging"; it is just never getting around to updating because you are keeping it so busy that it never has time to update the screen.

        You have a fundamental disconnect in your understanding of how Tk -- and guis in general -- work; between what you are expecting to happen and what actually happens.

        This is perhaps best illustrated by this piece of your code:

        $hl->itemConfigure( $randRow, 3, -text => "pending", -style => $style2 ); $hl->itemConfigure( $randRow, 3, -text => "waiting", -style => $style2 );

        First you change the text to "pending"; then immediately to "waiting". You are expecting the screen to update between the two changes such that a user might notice the change. That will never happen. Firstly, by default, the screen will not update until the program has nothing else to do. That means, at least until your changeItem() subroutine returns. So the first of the two changes in each branch of your while loop are completely redundant because they will never be shown on screen.

        But it is much worse than that. Your subroutine changes 100 items (twice each) every time it is called. And you are (attempting to) calling it every millisecond. So -- if that were possible, which it isn't -- each of the two changes would be on-screen for a maximum of half a millisecond. The human eye/brain simply cannot detect changes at anything close to that rate.

        Historically, movies were shown at 24 frames/second. Recently there have been moves to project movies at 48 frames/sec -- though most experts conclude that this is at least 50% higher than any human being can distinguish any difference. You are trying to achieve a rate of 2000 frames/sec.

        Besides that it is totally impossible; what would be the point? Jet fighter pilots reaction times can -- under absolutely ideal conditions of total immersion and rigourously-trained, muscle-memory actions -- achieve physical (finger) reactions to visual stimuli in just under 1/10th of 1 second.

        What are you hoping your user/operator will be able to do with seeing statuses change 2000 times a second?


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re^3: Perl tk gui hangs when large data thrown to it
by ww (Bishop) on Oct 15, 2013 at 16:03 UTC
    NO!

    As others have recommended: Simplify; create an example which illustrates the problem with fewer than 20 lines; (and, p.s. - don't whine).

    It's an extremely rare problem in this class that can't be duplicated without more than a few lines of code; in any case, the exercise of creating a brief example may illuminate your problem for you.

    My 'oops': intended as first reply to request (at Re^2: Perl tk gui hangs when large data thrown to it) for an email address.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1058285]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2014-09-24 01:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (244 votes), past polls