如何在Perl中制作动画加载标志?

时间:2019-07-12 16:58:49

标签: perl loading

我需要知道如何在Perl中制作一个动画加载标志,以便在程序检查更新时使人们保持娱乐。

我已经尝试使用

print ".";
sleep(0.1);
print ".";

但这似乎不起作用。 有人请帮助我!

print ".";
sleep(0.1);
print ".";

不起作用

我只希望程序等待1/10秒才能打印下一个.

4 个答案:

答案 0 :(得分:4)

使用Time::HiRes满足亚秒级计时需求,有几种方法

use warnings;
use strict;
use feature 'say';    
use Time::HiRes qw(sleep);

STDOUT->autoflush(1);  # or $| = 1;
my $tot_sleep = 0; 

# Print dots
print "Loading "; 
while (1) {
    $tot_sleep += sleep 0.1;  print ".";
    last if $tot_sleep >= 2;
} 
say " done\n";  $tot_sleep = 0;

# Print "spinning" cursor while waiting
print "Loading ... ";
WAIT: while (1) { 
    for (qw(- \ | /)) {
        print;  $tot_sleep += sleep (0.1);  print "\b";
        last WAIT if $tot_sleep >= 2;
    }   
}
say "\b done\n";

# Print (overwrite) percentile completed (if you know how long it takes)
my $tot_percent = 0;  
while ($tot_percent < 100) { 
    $tot_percent += 5;  
    print "Loading ... $tot_percent%\r"; 
    sleep 0.1;
} 
say "\n";

我通过等待2秒来模拟“完成”(加载)。这次if的检查代表检查“加载”是否完成,大概可以在代码中的那个时候完成(如果它是一个单独的线程/进程,或者该代码是否以派生方式运行)过程)。


对于一个也许更好的“旋转者”可以使用

use Time::HiRes qw(sleep);
use utf8;
use open qw(:std :encoding(UTF-8));
STDOUT->autoflush(1);

print "Waiting ... ";
WAIT: {
    my $tot_sleep;
    while (1) {
        for ('◑', '◒', '◐', '◓') {
            print; $tot_sleep += sleep 0.1; print "\b";
            last WAIT if $tot_sleep >= 5;
        }   
    }
};
say "\b done";

Term::Spinner::Color借来的符号的想法。

这样的“旋转者”当然不会像点子那样给出他们等待多长时间的视觉线索。

答案 1 :(得分:3)

现有解决方案假定您实际上要睡觉/等待。他们不容易适应用实际工作代替睡眠/等待。我的解决方案是在您进行实际工作(例如加载)时,而不仅仅是在等待一些东西。

use Time::HiRes qw( );

$| = 1;

{
   my @syms = qw( - \ | / );
   my ( $i, $t );

   sub start_spinner {
      $t = Time::HiRes::time;
      $i = 0;
      print $syms[$i];
   }

   sub update_spinner {
      my $now = Time::HiRes::time;
      return if $now - $time < 0.1;  # Prevent spinner from spinning too fast.

      $time = $now;
      $i = ( $i + 1 ) % @syms;
      print "\b$syms[$i]";
   }

   sub stop_spinner {
      print "\b \b";
   }
}

start_spinner();
for (1..500) {
   update_spinner();          # Call this as often as possible.
   Time::HiRes::sleep(0.01);  # Simulate a little bit of work.
}
stop_spinner();

关键是使用Time :: HiRes的高分辨率time(如有必要,还使用sleep)以及速率限制器(return if $now - $time < 0.1;)。

如果您确实要打印一行点,则可以使用相同的方法。

{
   my $t;

   sub start_spinner {
      $t = Time::HiRes::time;
   }

   sub update_spinner {
      my $now = Time::HiRes::time;
      return if $now - $time < 0.1;  # Prevent spinner from spinning too fast.

      $time = $now;
      print ".";
   }

   sub stop_spinner {
      print "\n";
   }
}

答案 2 :(得分:2)

标准sleep函数在整数秒内运行。您可以使用Time::HiRes中的sleep函数作为支持小数秒的直接替代。

use strict;
use warnings;
use Time::HiRes 'sleep';

sleep 0.1;

答案 3 :(得分:1)

另一种不使用模块的方法是滥用select()

use warnings;
use strict;
$|=1;

while (1){
    print '.';
    select(undef, undef, undef, 0.1);
}

或者,一个有趣的FreeBSD风格的微调程序(使用Linux系统调用刷新屏幕。在Windows上,将clear更改为cls):

while (1){
    for (qw(- \ | / -)){
        system 'clear';
        print $_;
        select(undef, undef, undef, 0.1);
    }
}