2

ボタンをクリックしているときに外部コマンドを実行できる Perl + Tkx のインターフェイスを作成しようとしています。

Tkモジュールの進め方についてはたくさんのドキュメントがありますが、Tkxについてはほとんどありません。

私はまだこのようなものをいくつか見つけましたが、私の例ではうまくいきません。特に、投稿には Tkx::open、Tkx::configure、Tkx::fileevent... の使用が含まれていますが、それらを組み合わせる方法がわかりません。

これが私が試しているコードです。ボタンをクリックし、キーを押して子プロセスを終了すると、Perl がエラーでクラッシュしますFree to wrong pool 16389d0 not 328e448 at C:/Perl/lib/Tcl.pm line 433.

注: ActivePerl 5.12.2 を使用しています。

use Tkx;
use strict;

my $mw = Tkx::widget->new(".");
my $button=$mw->new_ttk__button(-text => "Run", -command => [\&run_cmd, 0]);
$button->g_grid(-column => 0, -row => 0);
my $text = $mw->new_tk__text(-width => 32, -height => 16);
$text->configure(-state => "disabled");
$text->g_grid(-column => 0, -row => 1);
Tkx::MainLoop();

sub run_cmd {
    if (fork()==0) {
        system "pause";
        exit 0;
    }
}

ありがとう

4

1 に答える 1

1

この問題にほぼ2日を費やした後、Tkxに適応したTclのコードを記載した投稿のおかげで、最終的に答えを見つけました。

解決策は、使用することですTkx::open(いとこの「読み取り」および「閉じる」と組み合わせて)。

以下のコードは、GUI をブロックすることなくコマンドを正しく実行できますが、ほとんどの場合、STDOUT と STDERR を取得できませんでした (java で開発されたアプリケーションの実行では機能しましたが、systeminfoorでは機能しませんでしたdiff -v)。

誰かがそれについて洞察を得た場合は、遠慮なくコメントしてください。

ありがとう

use Tkx;
use strict;
use Data::Dumper;

my ($stdout,$stderr);

my $mw = Tkx::widget->new(".");
my $button=$mw->new_ttk__button(-text => "Run", -command => [\&run_command, "systeminfo"]);
$button->g_grid(-column => 0, -row => 0);
my $text = $mw->new_tk__text(-width => 32, -height => 16);
$text->insert("end", "Test\n");
$text->g_grid(-column => 0, -row => 1);

Tkx::MainLoop();
print "STDOUT: $stdout\n\n","-"x24,"\nSTDERR: $stderr\n";


sub run_command {
    my $cmd = shift;
    my $fh = Tkx::open("| $cmd", 'r') or die "$!";
    Tkx::fconfigure($fh, -blocking => 0);
    $stdout.=Tkx::read($fh);
    eval { Tkx::close($fh); };
    $stderr.=$@ if ($@);

}
于 2014-12-31T10:47:30.117 に答える