这里的窍门是添加布局和设置的调整回调不窗口,但布局。这不是完美的,它有点肮脏,但工作。初始定位工作不好,但有改进的空间。 必须检查Gtk.Widget和Gtk.Containers的请求,分配和自然大小,甚至使用Gdk方法。迟到了,希望这会让你朝正确的方向发展。
PS:我使用的是endless.png图片,但可以随意使用另一个图片,只需更改代码以反映它即可。
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: %d\n", 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;
}
非常感谢你:)但我有一个问题:你为什么说这是一个肮脏的方式?如果你有时间可以简单地解释如何以正确的方式来做到这一点? – guardian
@guardian sry刚刚阅读你的评论。那么,不是很脏,但不反映最好的办法。一个好主意是从[eog(gnome的眼睛,默认图像查看器)](https://github.com/GNOME/eog)检查代码。另一个方法是创建一个基于绘图区域的图像视图控件,并让开罗,例如,调整大小和绘制图像。有几个问题。当然,这个工作可以改进。在过去,我已经实施了这样的事情,甚至是专业的,并且很有效。 –
另外请注意,我保留原来的pixbuf并从那里调整大小。从图像中检索pixbuf会增加累积的重采样损失,并且图像质量会降低。 –