undef不是GtkWidget的Gtk2::Gdk::Drawable-Gtk2 perl自定义小部件调用窗口方法的类型

undef不是GtkWidget的Gtk2::Gdk::Drawable-Gtk2 perl自定义小部件调用窗口方法的类型,gtk,gtk2,Gtk,Gtk2,我正在尝试制作一个定制的PerlGTK2小部件。当我尝试访问GtkDrawingArea的窗口属性时,它返回unde而不是gdkdraawable对象。根据此方法,可以返回窗口对象或undef,但不清楚在什么条件下返回undef。有人能澄清一下吗 #!/usr/bin/perl use strict; use warnings; package Gtk2::MIDIPlot; use Gtk2; use base 'Gtk2::DrawingArea'; use Cairo; sub n

我正在尝试制作一个定制的PerlGTK2小部件。当我尝试访问GtkDrawingArea的
窗口
属性时,它返回
unde
而不是
gdkdraawable
对象。根据此方法,可以返回窗口对象或
undef
,但不清楚在什么条件下返回
undef
。有人能澄清一下吗

#!/usr/bin/perl

use strict;
use warnings;

package Gtk2::MIDIPlot;

use Gtk2;
use base 'Gtk2::DrawingArea';
use Cairo;

sub new {
  my $class = shift;
  my $this = bless Gtk2::DrawingArea->new(), $class;

  $this->set_size_request(14400, 768);

  return $this;
}

sub draw {
  my $drawArea = shift;

  my $thisCairoSurface = Gtk2::Gdk::Cairo::Context->create($drawArea->window);
}

package main;

use Gtk2 -init;

my $window = Gtk2::Window->new();

my $mainWidgetScroll = Gtk2::ScrolledWindow->new();
my $mainWidget = Gtk2::MIDIPlot->new();
$mainWidget->draw($mainWidget);
$mainWidgetScroll->add_with_viewport($mainWidget);
$mainWindow->add($mainWidgetScroll);

$window->signal_connect(destroy => sub{Gtk2->main_quit()});
$window->show_all();
Gtk2->main();

0;
通过查看,我发现我需要等待小部件的expose事件,然后才能对其进行绘制,因为直到该事件发生,窗口才被创建。此外,代码需要更好地适应GTK风格的设置,然后在回调中执行操作

#!/usr/bin/perl

use strict;
use warnings;

package Gtk2::MIDIPlot;

use Gtk2;
use base 'Gtk2::DrawingArea';
use Cairo;

sub new {
  my $class = shift;
  my $this = bless Gtk2::DrawingArea->new(), $class;

  $this->signal_connect(expose_event => 'Gtk2::MIDIPlot::draw');

  return $this;
}

sub draw {
  my $drawArea = shift;

  $drawArea->set_size_request(14400, 768);
  my $thisCairoSurface = Gtk2::Gdk::Cairo::Context->create($drawArea->get_window());
}

当小部件尚未“实现”时,它将返回
undef
。实现是将GdkWindow与GtkWidget关联的行为;未实现则相反。您需要了解如何在GTK+2上正确地使用cairo绘图,并将算法转换为Perl。(我相信这与
暴露
信号有关…)或者,您可以使用GTK+3,其中每个小部件都有一个
绘制
信号,该信号提供了自己的开罗上下文,您可以连接到该上下文来进行自定义绘制。谢谢@andlabs。我在下面发布了我的解决方案。我必须将绘图功能连接到曝光信号,以便为创建窗口留出时间。事实上,我已经看了我的答案中链接的例子来解决这个问题,但是谢谢你的评论。