我正在尝试创建一个小应用程序,该应用程序显示您在文件选择器中选择的图像。然后,当用户调整窗口大小时,它应该调整大小。
我的应用程序可以在我的类构造函数中添加此代码的程度,该代码应该使图像在调整窗口大小时可以调整大小的能力。
window.size_allocate.connect(() => {
resize_image(); //<-- a problem
});
当窗口更改大小时,此"应该"调用方法resize_image,但是每次添加此代码时,我运行基本操作系统的虚拟机都会崩溃并停止工作(我每次尝试运行程序时都必须重新启动(。
方法resize_image((的工作如下:
public void resize_image()
{
try
{ if(buf.get_width() < window.get_allocated_width()){
buf = buf.scale_simple(window.get_allocated_width(), window.get_allocated_width(), Gdk.InterpType.NEAREST);
image.set_from_pixbuf(buf);
}
}catch(Error e)
{
}
}
(我知道我的调整" Alogrithm"不是最好的,但我只是使用此方法进行测试。(
现在我的问题:为什么我的程序崩溃了?从PixBuf到图像的转换对于用户来说太慢了吗?有其他方法可以将图像大小调整到窗口大小吗?
任何帮助将不胜感激:(
这里的诀窍是添加一个布局,并将"调整回调"设置为不在窗口,而是将其设置为布局。它不是完美的,有点脏,但是有效。最初的定位不正常,但有改进的空间。必须检查gtk.widget和gtk.Containers是否要求,分配和自然尺寸,甚至使用GDK方法。迟到,希望这会带领您朝正确的方向发展。
ps :我正在使用一个无尽的图像,但请随时使用另一个图像,只需更改代码以反映它。
using Gtk;
public int main (string[] args) {
Gtk.Image image;
Gtk.Layout layout;
Gtk.Window window;
Gdk.Pixbuf pixbuf;
Gtk.init (ref args);
window = new Gtk.Window ();
layout = new Gtk.Layout ();
image = new Gtk.Image ();
try {
pixbuf = new Gdk.Pixbuf.from_file ("endless.png");
image = new Gtk.Image.from_pixbuf (pixbuf);
layout.put (image, 0,0);
window.add (layout);
layout.size_allocate.connect ((allocation) => {
print ("Width: %d Height: %dn", allocation.width, allocation.height);
var pxb = pixbuf.scale_simple (allocation.width, allocation.height, Gdk.InterpType.BILINEAR);
image.set_from_pixbuf (pxb);
});
window.destroy.connect (Gtk.main_quit);
window.show_all ();
Gtk.main ();
return 0;
} catch (Error e) {
stderr.printf ("Could not load file...exit (%s)n", e.message);
return 1;
}
}
编辑:
简单的开罗版本:
using Gtk;
using Cairo;
public int main (string[] args) {
Cairo.ImageSurface image;
image = new Cairo.ImageSurface.from_png ("endless.png");
Gtk.init (ref args);
var window = new Gtk.Window ();
var darea = new DrawingArea ();
window.add (darea);
window.show_all ();
darea.draw.connect ((cr) => {
float xscale;
float yscale;
cr.save ();
xscale = (float) darea.get_allocated_width () / image.get_width ();
yscale = (float) darea.get_allocated_height () / image.get_height ();
cr.scale (xscale, yscale);
cr.set_source_surface (image, 0, 0);
cr.paint ();
cr.restore ();
return true;
});
window.destroy.connect (Gtk.main_quit);
Gtk.main ();
return 0;
}
编辑2 :我创建了另一个版本以在2个图像之间切换,并在执行此操作时是否进行了多次检查,并检查内存是否增加,但事实并非如此。添加了几个盒子,并添加了2个按钮。
using Gtk;
using Cairo;
public int main (string[] args) {
Cairo.ImageSurface image;
image = new Cairo.ImageSurface.from_png ("endless.png");
Gtk.init (ref args);
var window = new Gtk.Window ();
var box1 = new Gtk.Box (Gtk.Orientation.VERTICAL, 0);
var box2 = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
var b1 = new Gtk.Button.with_label ("Image1");
var b2 = new Gtk.Button.with_label ("Image2");
box2.pack_start (b1, true, true, 0);
box2.pack_end (b2, true, true, 0);
var darea = new DrawingArea ();
box1.pack_start (box2, false, false, 0);
box1.pack_end (darea, true, true, 0);
window.add (box1);
window.show_all ();
b1.clicked.connect (() => {
image = new Cairo.ImageSurface.from_png ("endless.png");
darea.queue_draw ();
});
b2.clicked.connect (() => {
image = new Cairo.ImageSurface.from_png ("Gnome-logo.png");
darea.queue_draw ();
});
darea.draw.connect ((cr) => {
float xscale;
float yscale;
cr.save ();
xscale = (float) darea.get_allocated_width () / image.get_width ();
yscale = (float) darea.get_allocated_height () / image.get_height ();
cr.scale (xscale, yscale);
cr.set_source_surface (image, 0, 0);
cr.paint ();
cr.restore ();
return true;
});
window.destroy.connect (Gtk.main_quit);
Gtk.main ();
return 0;
}