如何从小部件 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;
}
您可以尝试多种方法。
删除旧图片并添加新图片
使用 gtk_container_get_children
检索旧图像(如果存在)并使用 gtk_container_remove
将其删除。然后像以前一样添加。
可以替换图片内容
同样,使用 gtk_container_get_children
检索旧图像(如果存在)并使用 gtk_image_set_from_pixbuf
.
替换内容
(除了上面的 1 或 2)
您还可以在创建容器时创建图像,并使用指向该图像的指针作为 user_data
进行回调。这将消除从您的容器中检索 child 的需要。
我目前正在使用 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;
}
您可以尝试多种方法。
删除旧图片并添加新图片
使用gtk_container_get_children
检索旧图像(如果存在)并使用gtk_container_remove
将其删除。然后像以前一样添加。可以替换图片内容
替换内容
同样,使用gtk_container_get_children
检索旧图像(如果存在)并使用gtk_image_set_from_pixbuf
.(除了上面的 1 或 2)
您还可以在创建容器时创建图像,并使用指向该图像的指针作为user_data
进行回调。这将消除从您的容器中检索 child 的需要。