Scroll Gtk2 GtkDrawingArea开罗绘图持久性(当滚动超出范围时)

Scroll Gtk2 GtkDrawingArea开罗绘图持久性(当滚动超出范围时),scroll,gtk,drawing,cairo,gtk2,Scroll,Gtk,Drawing,Cairo,Gtk2,我在一个GtkCrollingarea和开罗的GtkDrawingArea上画画。首先,我在曝光事件后绘制一个网格,然后捕获鼠标信号以在网格中绘制矩形。当我滚动时,网格仍然存在,但当我滚动出鼠标创建的矩形时,它们消失了,即使在我滚动回它们所在的区域后也是如此。首先,为什么网格保留而矩形不保留,对此我能做些什么?我可以保存每个矩形的位置,但是我还可以用其他什么方法来保存呢 #!/usr/bin/perl use strict; use warnings; package Gtk2::MIDIP

我在一个GtkCrollingarea和开罗的GtkDrawingArea上画画。首先,我在曝光事件后绘制一个网格,然后捕获鼠标信号以在网格中绘制矩形。当我滚动时,网格仍然存在,但当我滚动出鼠标创建的矩形时,它们消失了,即使在我滚动回它们所在的区域后也是如此。首先,为什么网格保留而矩形不保留,对此我能做些什么?我可以保存每个矩形的位置,但是我还可以用其他什么方法来保存呢

#!/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');
  $this->signal_connect(button_press_event => 'Gtk2::MIDIPlot::button_press');

  $this->set_events("button-press-mask");

  return $this;
}

sub draw {
  my $this = shift;

  $this->set_size_request(28800, 1536);
  my $thisCairo = Gtk2::Gdk::Cairo::Context->create($this->get_window());

  $thisCairo->set_line_width(1);
  $thisCairo->set_source_rgb(0.75, 0.75, 0.75);
  my $inc;
  for ($inc = 0; $inc <= 2400; $inc++) {
    $thisCairo->move_to($inc * 12, 0);
    $thisCairo->line_to($inc * 12, 1536);
  };
  for ($inc = 0; $inc <= 128; $inc++) {
    $thisCairo->move_to(0, $inc * 12);
    $thisCairo->line_to(28800, $inc * 12);
  };
  $thisCairo->stroke();
}

sub button_press {
  my $this = shift;
  my $event = shift;

  if ($event->button == 1) {
    my $x = $event->x;
    my $y = $event->y;

    my $thisCairo = Gtk2::Gdk::Cairo::Context->create($this->get_window());
    $thisCairo->rectangle($x - ($x % 12), $y - ($y % 12), 12, 12);
    $thisCairo->fill();
    $thisCairo->stroke();
  };
}

package main;

use Gtk2 -init;

my $window = Gtk2::Window->new();
my $mainWidgetScroll = Gtk2::ScrolledWindow->new();
my $mainWidget = Gtk2::MIDIPlot->new();
$mainWidgetScroll->add_with_viewport($mainWidget);
$window->add($mainWidgetScroll);
#/usr/bin/perl
严格使用;
使用警告;
包Gtk2::MIDIPlot;
使用Gtk2;
使用基础“Gtk2::DrawingArea”;
使用开罗;
次新{
我的$class=shift;
my$this=bless Gtk2::DrawingArea->new(),$class;
$this->signal_connect(expose_event=>'Gtk2::MIDIPlot::draw');
$this->signal_connect(按钮按下事件=>'Gtk2::MIDIPlot::按钮按下');
$this->set_事件(“按钮按下掩码”);
退还$this;
}
副抽{
我的$this=shift;
$this->set_size_请求(288001536);
我的$thisCairo=Gtk2::Gdk::Cairo::Context->create($this->get_window());
$thisCairo->设置线条宽度(1);
$thisCairo->set_source_rgb(0.75,0.75,0.75);
我的美元公司;
对于($inc=0;$inc移动到($inc*12,0);
$thisCairo->line_to($inc*121536);
};
对于($inc=0;$inc移动到(0,$inc*12);
$thisCairo->line_to(28800,$inc*12);
};
$thisCairo->stroke();
}
按下子按钮{
我的$this=shift;
我的$event=shift;
如果($event->button==1){
my$x=$event->x;
my$y=$event->y;
我的$thisCairo=Gtk2::Gdk::Cairo::Context->create($this->get_window());
$thisCairo->矩形($x-($x%12)、$y-($y%12)、12、12);
$thisCairo->fill();
$thisCairo->stroke();
};
}
主包装;
使用Gtk2-init;
my$window=Gtk2::window->new();
my$mainWidgetScroll=Gtk2::Scrolled窗口->新建();
我的$mainWidget=Gtk2::MIDIPlot->new();
$mainWidgetScroll->add_with_viewport($mainWidget);
$window->add($mainWidgetScroll);

我创建了一个要放置的对象的全局数组,并使用expose回调函数在该数组中绘制对象。所有持久性绘制都必须使用expose信号处理程序

#!/usr/bin/perl

use strict;
use warnings;

package Gtk2::MIDIPlot;

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

my $gtkObjects = [];

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

  $this->signal_connect(expose_event => 'Gtk2::MIDIPlot::expose');
  $this->signal_connect(button_press_event => 'Gtk2::MIDIPlot::button');

  $this->set_events("button-press-mask");

  $this->set_size_request(28800, 1536);

  return $this;
}

sub expose {
  my $this = shift;

  my $thisCairo = Gtk2::Gdk::Cairo::Context->create($this->get_window());

  $thisCairo->set_line_width(2);
  $thisCairo->set_source_rgb(0.75, 0.75, 0.75);

  my $inc = 0;

  for ($inc = 0; $inc <= 2400; $inc++) {
    $thisCairo->move_to($inc * 12, 0);
    $thisCairo->line_to($inc * 12, 1536);
  };

  for ($inc = 0; $inc <= 128; $inc++) {
    $thisCairo->move_to(0, $inc * 12);
    $thisCairo->line_to(28800, $inc * 12);
  };

  $thisCairo->stroke();

  $thisCairo->set_source_rgb(0, 0, 0);
  if(@{$gtkObjects}) {
    foreach(@{$gtkObjects}) {
      if(@{$_}[0] eq 'rect') {
        my ($x, $y) = (@{$_}[1], @{$_}[2]);

        $thisCairo->rectangle($x - ($x % 12), $y - ($y % 12), 12, 12);
        $thisCairo->fill();
      };
    };
  };

  $thisCairo->stroke();
}

sub button {
  my $this = shift;
  my $event = shift;

  if ($event->button == 1) {
    my $x = $event->x;
    my $y = $event->y;

    push(@{$gtkObjects}, ['rect', $x, $y]);
    $this->expose;
  };
}

package main;

use Gtk2 -init;

my $window = Gtk2::Window->new();
my $mainWidgetScroll = Gtk2::ScrolledWindow->new();
my $mainWidget = Gtk2::MIDIPlot->new();
$mainWidgetScroll->add_with_viewport($mainWidget);
$window->add($mainWidgetScroll);
!/usr/bin/perl
严格使用;
使用警告;
包Gtk2::MIDIPlot;
使用Gtk2;
使用基础“Gtk2::DrawingArea”;
使用开罗;
我的$gtkObjects=[];
次新{
我的$class=shift;
my$this=bless Gtk2::DrawingArea->new(),$class;
$this->signal_connect(expose_事件=>'Gtk2::MIDIPlot::expose');
$this->signal_connect(按钮按下事件=>'Gtk2::MIDIPlot::按钮');
$this->set_事件(“按钮按下掩码”);
$this->set_size_请求(288001536);
退还$this;
}
次曝光{
我的$this=shift;
我的$thisCairo=Gtk2::Gdk::Cairo::Context->create($this->get_window());
$thisCairo->设置线条宽度(2);
$thisCairo->set_source_rgb(0.75,0.75,0.75);
我的$inc=0;
对于($inc=0;$inc移动到($inc*12,0);
$thisCairo->line_to($inc*121536);
};
对于($inc=0;$inc移动到(0,$inc*12);
$thisCairo->line_to(28800,$inc*12);
};
$thisCairo->stroke();
$thisCairo->set_source_rgb(0,0,0);
if(@{$gtkObjects}){
foreach(@{$gtkObjects}){
if(@{$}[0]eq'rect'){
my($x,$y)=(@{$}[1],@{$}[2]);
$thisCairo->矩形($x-($x%12)、$y-($y%12)、12、12);
$thisCairo->fill();
};
};
};
$thisCairo->stroke();
}
子按钮{
我的$this=shift;
我的$event=shift;
如果($event->button==1){
my$x=$event->x;
my$y=$event->y;
push(@{$gtkObjects},['rect',$x,$y]);
$this->expose;
};
}
主包装;
使用Gtk2-init;
my$window=Gtk2::window->new();
my$mainWidgetScroll=Gtk2::Scrolled窗口->新建();
我的$mainWidget=Gtk2::MIDIPlot->new();
$mainWidgetScroll->add_with_viewport($mainWidget);
$window->add($mainWidgetScroll);