Dave Lowe
Dave Lowe

Reputation: 35

Perl Curses::UI - Loops

I'm new to Perl and Curses but I'm struggling to get my code to run a loop, to start with here's my code:

#!/usr/bin/env perl

use strict;
use Curses::UI;

sub myProg {
    my $cui = new Curses::UI( -color_support => 1 );

    my $win = $cui->add(
        "win", "Window", 
        -border => 1, 
    );

    my $label = $win->add(
        'label', 'Label', 
        -width         => -1, 
        -paddingspaces => 1,
        -text          => 'Time:', 
    );
    $cui->set_binding( sub { exit(0); } , "\cC");

    # I want this to loop every second 
    $label->text("Random: " . int(rand(10)));
    sleep(1);

    $cui->mainloop();

}

myProg();

As you can see I want this section to run recursively:

    # I want this to loop every second 
    $label->text("Random: " . int(rand(10)));
    sleep(1);

The idea of putting a random number in a label is just to show it works, I will eventually have quite a few labels that will be changed regularly and would like to do other functions as well.

I've tried doing:

while (1) {
    ...
}

but if I do this before the mainloop(); call the window is never created and after the call it does nothing?

Hope this makes sense? So how do I do it?

Upvotes: 2

Views: 1696

Answers (1)

themel
themel

Reputation: 8895

Curses takes over execution flow of your program once you launch the main loop and only return control to you via callbacks that you have set up before. In this paradigm, you don't do time-dependent tasks with sleep() loops, you ask the system to periodically call you back for the updates.

Restructuring your program to do just that, via the (undocumented) Curses::UI timers:

#!/usr/bin/env perl

use strict;
use Curses::UI;

local $main::label;

sub displayTime {
    my ($second, $minute, $hour, $dayOfMonth, $month, $yearOffset, $dayOfWeek, $dayOfYear, $daylightSavings) = localtime();
    $main::label->text("Time: $hour:$minute:$second");
}

sub myProg {
    my $cui = new Curses::UI( -color_support => 1 );

    my $win = $cui->add(
        "win", "Window",
        -border => 1,
    );

    $main::label = $win->add(
        'label', 'Label',
        -width         => -1,
        -paddingspaces => 1,
        -text          => 'Time:',
    );
    $cui->set_binding( sub { exit(0); } , "\cC");
    $cui->set_timer('update_time', \&displayTime);


    $cui->mainloop();

}

myProg();

If you need to vary your timeout, set_timer also accepts a time as an additional argument. Related functions enable_timer, disable_timer, delete_timer.

Source: http://cpan.uwinnipeg.ca/htdocs/Curses-UI/Curses/UI.pm.html#set_timer-

Upvotes: 6

Related Questions