在Perl加X窗口中没有事件循环图形



在20世纪80年代的Apple II BASIC上,你会使用"HGR"来进入屏幕,"HCOLOR"会设置颜色,"HPLOT"会绘制点。您还可以操作屏幕字节数据,并且不必将程序控制权交给任何事件处理程序。如今,每种语言和每一个库似乎都缺少这种荒谬的基本功能。

因此,我使用X Window API在C中编写了一个小库来实现这一点:HGR(X,y)设置了一个XWindow,HCOLOR(I)设置了颜色,HPLOT(I,j)绘制了一个点,此外,您还可以提取窗口的位图,并可以修改它并显示修改后的内容。这并不简单,我不想再经历一次。

我现在正在使用Perl做一些事情,我需要这样一个Perl工具,在这里你可以调用一个子程序,该子程序最好在不生成新线程的情况下返回,输出一个窗口,在那里你可以向窗口添加图形内容,并在程序感兴趣时查询事件。这是20世纪80年代BASIC的功能,所以应该不难。但我看到的工具并没有做到这一点:

  • GD:据我所见,这会生成图形文件,而不是图形窗口。看来你需要把它传送到另一个程序
  • Gtk2:我必须拿出一个单独的线程来捕捉事件,否则它将不会显示窗口。我不想分叉任何东西,而且我基本上不关心任何事件,除非我明确要求稍后查看堆积在队列中的东西
  • Qt:在这里,您还需要将控制权移交给事件处理程序,不移交,不显示。在C++版本中,我可以让Qt显示和绘制,而无需切换
  • PerlTk:又是一次愚蠢的交接
  • OpenGL:在这里,当我想看看发生了什么时,我不知道如何捕捉X窗口事件,比如按键

有人知道如何从正在运行的应用程序中建立XWindow,而不需要分叉GUI应用程序进程,在那里你可以在窗口中绘制点和线等基本内容,在哪里你可以按照自己的时间表查询窗口的事件吗?我简单地看了一下Perl的X Window API,它和C一样可怕,C代码与Perl的接口也很可怕。如果有必要,我会做的。但也许不会。Perl已经有HGR了吗?

如果你想知道我的意思,没有事件循环图形库,请参阅这篇链接的论文,不幸的是,这篇论文是针对C的。除了介绍性编程课程之外,这篇文章对科学知识非常有用。

几乎每个GUI工具包都支持在不进入事件循环的情况下构建窗口。以下是的示例

#!/usr/bin/perl --
use strict;
use warnings;
use Tk;
my $mw = tkinit();
my $ca = $mw->Canvas(
background => 'white'
)->pack(qw/-expand 1 -fill both /);
$mw->geometry( '500x600+10+10' );
for my $cc (
{ red   => &red, green => &der, blue => &erd },
{ green => &red, red   => &der, blue => &erd },
{ green => &red, blue  => &der, red  => &erd },
)
{
$ca->delete('all');
my %color = %$cc;
for my $fill ( keys %color ) {
my $red = $color{$fill};
for my $t ( 10 .. 220 ) {
my $d = 0.1;
my ( $x, $y ) = $red->( $t, 0.1 );
$_ += 250 for $x, $y;
$ca->createOval(
$x, $y,
( $t * 2 * $d ) + $x,
( $t * 2 * $d ) + $y,
-fill => $fill,
);
$mw->update;
select undef, undef, undef, 0.001;
}
$mw->update;
}
}
Tk::DoOneEvent(0) while Tk::MainWindow->Count; ## MainLoop;
exit 0;
sub red {
my ( $t, $d ) = @_;
my $x = $t * sin( $t * $d );
my $y = $t * cos( $t * $d );
$x, $y;
}
sub der {
my ( $t, $d ) = @_;
my $x = $t * sin( $t * $d );
my $y = $t * cos( $t * 2 * $d );
$x, $y;
}
sub erd {
my ( $t, $d ) = @_;
my $x = $t * sin( $t * 2 * $d );
my $y = $t * cos( $t * $d );
$x, $y;
}
__END__

Gtk2和Wx都支持相同的东西,它要么更新/显示/显示。。。窗口被绘制出来,当你想要用户交互时,你调用MainLoop或运行应用程序或自己处理它,这只是一段时间的循环调度未决事件

wxTheApp->Dispatch       while wxTheApp->Pending;
Gtk2->main_iteration     while Gtk2->events_pending;

我建议使用Perl模块Inline::C。该模块使向Perl应用程序公开C库变得容易。对于一些C库,"AUTOWRAP"选项使其变得非常琐碎。但是,即使您必须自己编写一些包装器,内联::C也确实减轻了XS的负担。

我不确定你的最终目标是什么,这可能没有帮助,但也许你想看看David Merten的App::Prima::REPL。David一直在为Perl/PDL构建一个基于Prima图形工具包的绘图库。为了将其发挥到逻辑的极致,他围绕它构建了一个REPL,制作了一个内置绘图的GUI REPL。正如您所说,Prima依赖于事件循环来运行,但是,因为您在REPL中,所以您仍然可以指示REPL绘制新数据。他的目标也是科学使用!

在这种情况下,我认为您有点错过了GLib/GTK之类的情节。在不分叉的情况下处理GTK是非常有可能的;事实上,如果你做叉子之类的事情,你很可能做错了。使用GTK,您所描述的内容应该很容易实现。

相关内容

  • 没有找到相关文章

最新更新