valagtk4

Replace a paintable with another in vala Gtk4


I want to make my app change image for another when a button is clicked vala with Gtk4.

 public class Main : Object
{
    public static int main()
    {
        var app = new Gtk.Application ("example.com.Demo", ApplicationFlags.FLAGS_NONE);

        app.activate.connect
        (() => {
            var window = new Gtk.ApplicationWindow(app);

            var image = new Gtk.Picture.for_filename("img1.jpg");
            var button = new Gtk.Button.with_label("Change Image");
            button.clicked.connect(
                // how to change the image
            );

            var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
            box.append(image);
            box.append(button);

            window.set_child(box);
            window.present();
            image.show();
        });
        return app.run();
    }
}

I've tried using a Gtk.Image() and the method image.set_from_paintable which fails with the error:

: error: Argument 1: Cannot convert from `Gtk.Picture' to `unowned Gdk.Paintable?'
   29 |                 image.set_paintable(new Gtk.Picture.for_filename("img2.jpg"));

I've also tried using a container var box = new Gtk.Box(...) removing one Gtk.Picture and appending the second one, which I could not make work.


Solution

  • What worked was declaring the two pictures first and using a container to remove the image and append the second:

     public class Main : Object
    {
        public static int main()
        {
            var app = new Gtk.Application ("example.com.Demo", ApplicationFlags.FLAGS_NONE);
    
            app.activate.connect
            (() => {
                var window = new Gtk.ApplicationWindow(app);
    
                var image1 = new Gtk.Picture.for_filename("img1.jpg");
                var image2 = new Gtk.Picture.for_filename("img2.jpg");
    
                var container = new Gtk.Box(Gtk.Orientation.Vertical, 10);
                container.append(image1);
    
                var button = new Gtk.Button.with_label("Change Image");
                button.clicked.connect(
                    container.remove(image1);
                    container.append(image2);
                );
    
                var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
                box.append(image);
                box.append(button);
    
                window.set_child(box);
                window.present();
                image.show();
            });
            return app.run();
        }
    }