0

システム コマンドの進行状況を表示するトップレベル ウィンドウを構築しようとしています。GUIをアクティブにしたいので(フリーズして「応答しない」ことはありません)、「キャンセル」ボタンを押すとプロセスが強制終了されます。それ以外の場合は、終了時に「閉じる」ボタンをアクティブにして「キャンセル」を無効にします。以前の質問の 1 つに対する提案に従って、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秒待たずに)?

ありがとう、マーク。

4

2 に答える 2

1

(任意のTkウィジェットの)afterメソッドを使用すると、コールバックが将来特定のミリ秒数で発生するようにスケジュールでき、waitVariableメソッド(ページで検索する必要があります)は、変数が設定されるまでイベントループを実行します。

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であまりコーディングしていないので、別の言語で行うことを翻訳しています…)

于 2012-10-28T19:08:09.483 に答える
1

Time::HiRes::usleep を使っています。

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

これはやり過ぎかもしれませんが、ある時点で UI アプリケーションが成長し、高解像度タイマーを使用して、アプリケーション全体で非同期にイベントをディスパッチしてリッスンする必要が生じます。この目的のために、POEフレームワークは優れた資産だと思います。

私は特に wxWidgets で POE を使用していますが、Tk: POE::Loop::Tkとも互換性があります。

于 2012-10-28T16:37:42.410 に答える