如何从小部件 gtk c 中删除图像?

How to remove an image from a widget gtk c?

我目前正在使用 gtk 开发用户界面。 我现在所做的是,您可以 select 文件中的图像并使用“打开”按钮显示它。 问题是,当我打开第二张图片时,它会将图片添加到 window 而不会删除当前图片。 我想知道当用户选择打开另一个图像时如何更改显示的图像。 我的代码:


#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>

#include "SDL/SDL.h"
#include "SDL/SDL_image.h"

#include "../Threshold/delete_color.h"


#define GTK_STOCK_CANCEL ((GtkStock)"gtk-cancel")


GtkWidget *image; 
gchar* path;


void cb_quit(GtkWidget *p_widget, gpointer user_data)
{
    gtk_main_quit();
    (void)p_widget;
    (void)user_data;
}

void solve(const gchar* path)
{
    SDL_Surface* image;

    // Binarization
    image = binarization((char*) file_name);
    SDL_SaveBMP(image, "binarize.bmp");

    // Rotation
    //rotation(image);
    SDL_SaveBMP(image, "rotation.bmp");

    // Grid Detection
    SDL_SaveBMP(image, "grid.bmp");

    // Case detection
    // TODO
    
    // Get the grid.txt
    // TODO
    
    // Get the grid solution
    // TODO

    // Create the solution image
    // TODO
}
static void set_image(const gchar *file_name, gpointer user_data)
{
    GtkWidget *pVBox;
    GdkPixbuf *pixbuf;
    GError *error = NULL;

    pVBox = (GtkWidget*) user_data;
    
    int width = gtk_widget_get_allocated_width(pVBox);
    int height = gtk_widget_get_allocated_height(pVBox);

    pixbuf = gdk_pixbuf_new_from_file("result.bmp", &error);

    if (!error)
    {
        GdkPixbuf *pixbuf_mini = NULL;
        pixbuf_mini = gdk_pixbuf_scale_simple(pixbuf,
                width,
                height - 200,
                GDK_INTERP_NEAREST);

        image = gtk_image_new_from_pixbuf(pixbuf_mini);
        gtk_container_add(GTK_CONTAINER(pVBox), image);
        gtk_widget_show(image);
    }
}

void cb_open(GtkWidget *p_widget, gpointer user_data)
{
    GtkWidget *p_dialog = NULL;
    p_dialog = gtk_file_chooser_dialog_new("Open file", NULL,
            GTK_FILE_CHOOSER_ACTION_OPEN,
            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
            GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
            NULL);

    if(gtk_dialog_run (GTK_DIALOG (p_dialog)) == GTK_RESPONSE_ACCEPT)
    {
        gchar *file_name = NULL;
        path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (p_dialog));
        file_name = path;
        g_print("%s\n", path);
        set_image(file_name, user_data);
        g_free (file_name), file_name = NULL;
    }

    gtk_widget_destroy(p_dialog);
    (void)p_widget;
}

int main(int argc, char **argv)
{
    GtkWidget *p_window = NULL;
    GtkWidget *p_main_box = NULL;

    // Initialisation
    gtk_init (&argc, &argv);

    // Main window
    p_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position(GTK_WINDOW(p_window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(p_window), 600, 400);
    g_signal_connect (G_OBJECT (p_window), "destroy",
            G_CALLBACK (cb_quit), NULL);

    // Main container
    p_main_box = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER (p_window), p_main_box);

    // Exit button
    {
        GtkWidget *p_button = NULL;
        p_button = gtk_button_new_with_label("Exit");
        g_signal_connect(G_OBJECT (p_button), "clicked", G_CALLBACK (cb_quit), NULL);
        gtk_box_pack_start(GTK_BOX (p_main_box), p_button, FALSE, FALSE, 0);
    }

    // Open button
    {
        GtkWidget *p_button = NULL;
        p_button = gtk_button_new_with_label ("Open");
        g_signal_connect (G_OBJECT (p_button), "clicked", G_CALLBACK (cb_open), (gpointer*) p_main_box);
        gtk_box_pack_start (GTK_BOX (p_main_box), p_button, FALSE, FALSE, 0);
    }

    // Display
    gtk_widget_show_all(p_window);
    g_print("%s\n", path);
    gtk_main();
    return EXIT_SUCCESS;
}

您可以尝试多种方法。

  1. 删除旧图片并添加新图片
    使用 gtk_container_get_children 检索旧图像(如果存在)并使用 gtk_container_remove 将其删除。然后像以前一样添加。

  2. 可以替换图片内容
    同样,使用 gtk_container_get_children 检索旧图像(如果存在)并使用 gtk_image_set_from_pixbuf.

    替换内容
  3. (除了上面的 1 或 2)
    您还可以在创建容器时创建图像,并使用指向该图像的指针作为 user_data 进行回调。这将消除从您的容器中检索 child 的需要。