如何在Vala中将图像大小调整为窗口大小

时间:2017-04-20 15:43:04

标签: resize window gtk vala gdkpixbuf

我正在尝试创建一个小应用程序,它显示您在文件选择器中选择的图像。然后,当用户调整窗口大小时,它应该调整大小。

我的应用程序可以直接将我的代码添加到我的类的构造函数中,这样可以使图像在调整窗口大小时调整大小。

window.size_allocate.connect(() => {

        resize_image(); //<-- a problem

    });

这&#34;应该&#34;当窗口改变其大小时调用方法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)
    {
    }
}

(我知道我的调整大小&#34; alogrithm&#34;不是最好的,但我只是用这种方法进行测试。)

现在我的问题: 为什么我的程序崩溃了?对于用户来说,从pixbuf到图像的转换是否太慢? 还有另一种方法可以将图像大小调整为窗口大小吗?

任何帮助将不胜感激:)

1 个答案:

答案 0 :(得分:1)

这里的技巧是添加布局并将调整大小回调设置为不是窗口而是布局。它并不完美,它有点脏,但有效。初步定位不好,但有改进的余地。 必须检查Gtk.Widget和Gtk.Containers的请求,分配和自然大小,甚至使用Gdk方法。迟到了,希望这会引导你朝着正确的方向前进。

PS :我正在使用endless.png图片,但可以随意使用另一张图片,只需更改代码即可反映出来。

Run_N+1

修改

一个简单的开罗版本:

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;
    }
}

编辑2 : 我已经创建了另一个版本来切换2个图像,并检查是否在这样做了几次并检查内存是否增加,但事实并非如此。添加了几个Box,并添加了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 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;
}