【问题标题】:Perl TK with Proc::Background proper usage (keep GUI active?)Perl TK 与 Proc::Background 正确使用(保持 GUI 活动?)
【发布时间】:2012-10-18 00:04:46
【问题描述】:

我正在尝试构建一个显示系统 cmd 进度的顶级窗口。我希望 GUI 处于活动状态(没有冻结和“无响应”),因此按下“取消”按钮将终止进程,否则,完成后,激活“关闭”按钮并禁用“取消”。根据对我之前的一个问题的建议,我尝试使用 Proc::Background。我发现这样做的唯一方法是:

my $proc1;

my $cancel = $toplevel->Button(-text => "Cancel", -command =>sub{$proc1->die;})->pack;
my $close = $toplevel->Button(-text => "Close", -command =>sub{destroy $toplevel;}, -state=>"disabled")->pack;

$proc1 = Proc::Background->new("x264.exe $args");

while ($proc1->alive == 1){
    $mw->update();
    sleep(1);
}

$cancel->configure(-state=>'disabled');
$close->configure(-state=>'normal');

还有其他更有效的方法吗(无需等待 1 秒的响应)?

谢谢, 标记。

【问题讨论】:

  • 你可以写select(undef,undef,undef,0.2);来等待0.2秒的响应。

标签: perl cmd system fork tk


【解决方案1】:

我使用 Time::HiRes::usleep。

use Time::HiRes qw(usleep);
while ($proc1->alive == 1){
    $mw->update();
    usleep(100_000); //0.1 seconds
}

对于这个问题,这可能有点过头了,但在某些时候,我们的 UI 应用程序会增长,我们迫切需要使用高分辨率计时器,并在整个应用程序中异步分派和侦听事件。为此,我发现POE 框架是一个很好的资产。

我特别将 POE 与 wxWidgets 一起使用,但它也与 Tk 兼容: POE::Loop::Tk

【讨论】:

    【解决方案2】:

    after method(任何 Tk 小部件)允许您将回调安排在未来的特定毫秒数内发生,waitVariable method(您需要在页面中搜索)将运行事件循环直到设置了变量。

    my $proc1;
    my $cancel = $toplevel->Button(-text => "Cancel", -command =>sub{$proc1->die;})->pack;
    $proc1 = Proc::Background->new("x264.exe $args");
    my $procDone = 0;
    my $timercb = sub {
        if ($proc1->alive) {
            $toplevel->after(100, $timercb);
        } else {
            $procDone = 1; # Anything really
        }
    };
    $timercb();
    $toplevel->waitVariable(\$procDone) unless ($procDone);
    

    (我不确定这段代码是否有效;这些天我在 Perl 中编写的代码不多,所以我正在翻译我在 another language... 中所做的事情)

    【讨论】:

    • 看起来可行。但是递归执行它不是矫枉过正吗?
    • 它应该只是在未来重新安排自己 100 毫秒,但我可能有点错了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多