我该如何在GUI中显示Perl控制台输出?

9

我有几个简单的Perl程序,输出到标准输出,但这样会有一些问题:

  • 我的一些用户害怕控制台
  • 我的用户使用Windows,因此我的程序输出显示在cmd控制台上,所以我无法控制其显示方式(颜色和终端大小),更糟糕的是,控制台不可调整大小(至少在宽度方面)

为了解决这些问题,我希望能够将输出作为一个简单的GUI界面选项显示。GUI应该对程序完成之前做出响应(在运行时可以滚动或调整窗口大小)。

我可以使用哪些简单的工具包和小部件来实现这一点?(我在Windows上使用ActivePerl进行开发。)

5个回答

10

你可以使用任何GUI选项,然后可以使用Tie::STDOUT来重新定义printprintf的行为,将输出转储到你选择的小部件中。唯一的问题是,使用匿名子程序使其跨包与你的小部件通信可能会很混乱。这里有一个简短而粗略的示例,使用Win32::GUI:

use Win32::GUI();
use Tie::STDOUT 
    print => sub {
        $main::textfield->Append(@_);
    };

my $main = Win32::GUI::Window->new(
        -name => 'Main',
        -text => 'Perl',
        -width => 220,
        -height => 230,
    );
our $textfield = $main->AddTextfield(
        -name   => "Output",
        -left   => 8,
        -top    => 8,
        -width  => 180,
        -height => 180,
        -readonly => 1,
        -multiline => 1,
        -vscroll => 1,
    );
$main->Show();
sub Main_Terminate {
        -1;
}


if(!fork()) {
    print "Hello.\n";
    for (1..20) {
      sleep 1;
      printf "More output %d\n", $_;
    }
} else {
    Win32::GUI::Dialog();
}

注意,在结尾处调用Win32::GUI::Dialog()以防止窗口在脚本结束后立刻关闭。


这是一个不错的开始。但还有一个问题:GUI 在程序到达 Win32::GUI::Dialog 之前无响应。也许我应该尝试使用两个线程? - Jazz
@Jazz:是的,实际上你可以使用 fork(),Windows 的 fork 模拟会为你处理它。我已经编辑了我的答案以显示更改。 - Adam Bellaire

6

使用Perl和NCurses不能解决我的问题。对于wxPerl、PerlTK或GTK,我如何重定向控制台输出? - Jazz
您需要创建一种标准化的通信方式,与运行控制台应用程序并发送输入的 GUI 应用程序进行通信。或者您可以重写该应用程序。 - monksy
在输出到控制台方面,没有共享的标准,因此没有自动将控制台应用程序转换为基于 GUI 的应用程序的神奇过程。 - monksy

4
如果您在计算机上安装了Firefox,我已经在模块XUL::Gui上进行了工作,它可以使用Firefox的渲染引擎显示您的Perl GUI。在Adam的回答基础上进行改进:
use XUL::Gui;
use Tie::STDOUT 
    print => sub {$ID{text}->value .= join '' => @_};

display Window title=>'Perl', minwidth=>640, minheight=>480,
    TextBox( FILL SCROLL id=>'text', multiline=>'true' ),
    delay {
        print "hello world\n";  # Output goes to the window.
        for (1..5) {
            printf "More output %d\n", $_;
        }
    };

编辑:修复了与GUI多行返回值相关的错误,上面的示例现在更好了。适用于XUL::Gui 0.35及以上版本。


仅从代码上看,我期望是 .= join($,, @_) . $\\,但实际上我还没有尝试过。 - ephemient

1

wxWidgets使用Wx CPAN模块目前在Perl世界中很受欢迎(参见Padre)。

然而,我不确定这是否包含在ActivePerl中,我相信可能会与Tk一起提供。

/I3az/


从5.10版本开始,ActivePerl使用Tkx代替Tk,尽管Tk仍然可以通过PPM获得。(Tkx是Tcl/Tk的另一组绑定的选择。) - Michael Carman
@Jazz - 你可以考虑使用消息/日志队列选项,而不是在STDOUT上玩耍。例如,像Message::Stack(http://search.cpan.org/dist/Message-Stack/)这样的东西。 - draegtun
我可以使用Tie::STDOUT或Message::Stack,这并不是真正的问题。我剩下的问题是如何在程序运行时拥有一个响应式GUI来显示输出。 - Jazz

0

Win32::Console::ANSI 可以控制命令行窗口的背景、文本颜色和位置,以及大小和标题。

据我所知,它不允许鼠标输入,但如果您只是显示程序进度,这可能已经足够了。

另一个可能性是用 html/javascript 重写程序,并具有完全的交互能力。

我经常在 perl 中完成繁重的工作,然后构建并编写一个 html 程序进行用户交互。

或者使用标准的 html 程序,让 perl 在调用 html 程序之前写出特定的数据 json 文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接