滚动超出范围时 Gtk2 GtkDrawingArea Cairo 绘图持久性
Gtk2 GtkDrawingArea Cairo drawing persistence when scrolled out of range
我正在使用 Cairo 在 GtkScrollingArea 中的 GtkDrawingArea 上绘图。首先我在 expose 事件后绘制一个网格,然后我捕获鼠标信号以在网格中绘制矩形。当我滚动时,网格仍然存在,但是当我滚动到鼠标创建的矩形的视线之外时,它们消失了,即使我滚动回它们所在的区域也是如此。所以一方面,为什么网格仍然存在而矩形仍然存在不是,我该怎么办?我可以保存每个矩形的位置,但我可以通过哪些其他方式来做到这一点?
#!/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
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);
我正在使用 Cairo 在 GtkScrollingArea 中的 GtkDrawingArea 上绘图。首先我在 expose 事件后绘制一个网格,然后我捕获鼠标信号以在网格中绘制矩形。当我滚动时,网格仍然存在,但是当我滚动到鼠标创建的矩形的视线之外时,它们消失了,即使我滚动回它们所在的区域也是如此。所以一方面,为什么网格仍然存在而矩形仍然存在不是,我该怎么办?我可以保存每个矩形的位置,但我可以通过哪些其他方式来做到这一点?
#!/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
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);