0

以下は、TK を使用した Perl のコードの例です。

my $btn_start = $mw->Button(-image => $img_start, -command => \&start)->pack;
MainLoop;


sub start{
my $topWin = $mw -> Toplevel;
my $entry = $topWin->Label(-textvariable=>\my $process)->pack();
$process="start 1st";
system("long_command.exe");
$process.="\nstart 2nd";
system("another_command.exe");
.
.
.
$process.="\nstart nth";
system("ncommand.exe");
}

問題は、ボタンを押すと、 system() コマンドが実行を終了した後にのみトップレベルのウィンドウが開くことです (なぜ他のコマンドよりも先に開始するのですか??)。各 system() コマンドの後にステータスを更新しようとしています。

あなたがアドバイスしていただけますか?

よろしくお願いします、マーク。

4

4 に答える 4

4

system() コマンドを実行する前に、

$mw->update()

声明。何が起こるかというと、メイン ループが時々ウィンドウを更新するということです。あなたの場合、次のスケジュールされた更新が発生する前に(start()がメインループに戻ったときにのみ発生する可能性があります)、system()が呼び出され、それが戻るまで何も実行されません-すべてが同じプロセスで実行されるためです.

ただし、適切に処理したい場合は、プロセスをフォークする必要があります。そうしないと、コマンドの実行中にアプリケーションが反応しなくなります。

于 2012-10-15T16:29:55.600 に答える
1

[注: 私は実行中の Tk にアクセスできないため、以下は第一原理とドキュメントに基づく推測です。あなたは警告されました。]

UI を更新するために、Tk が制御を取り戻していません。何が起こっているかというと、新しい を作成しましたが、描画できるようにTopLevel制御を戻していないということです。MainLoop最終的にstartは制御を戻しMainLoop、保留中のすべての更新を一度に実行します。

サブの途中でUIを更新したい場合はupdate、最も外側の興味深いものを定期的に呼び出して、呪文のWidget制御を戻す必要があります. MainLoopあなたの場合、それは

$mw->update();

perldoc Tk::Widgetも参照updateしてください。

于 2012-10-15T16:53:11.357 に答える
1

あなたの場合、ユーザーインターフェイス(ボタン、ラベルなど)とそれらが実行するタスク(system)は、両方とも同じプロセスと同じスレッドで実行されています。これは、GUI プログラムを作成する単純な方法です。

探している効果 (バックグラウンドで他の処理が行われているときにユーザー インターフェイスがアクティブになる) を得るには、それらを同時に実行する方法を調べる必要があります。

于 2012-10-15T16:30:29.280 に答える
0

問題は、サブプロセスが完了するのを待つ間、(同じスレッド内の)すべてsystemを停止することです。これには、あらゆる種類のもの(再描画を含む)を駆動するために使用されるGUIイベントキューの提供を停止することが含まれます。Proc :: Backgroundモジュールを使用してサブプロセスを非同期で実行することを検討してください(コードにとって重要なのは一度に1つだけであると想定して、1つのタスクが終了し、次のタスクを開始する必要があるかどうかを判断する定期的なタイマーを使用します)。

于 2012-10-16T10:34:13.433 に答える