如何在应用程序运行时更改GtkImage的“file”属性

时间:2009-10-14 02:40:04

标签: gtk

我想在用户点击按钮时更改GtkImage上的图像,所以我尝试了下面的代码,但它不起作用。

/*
 * Compile me with:
 *   gcc -o tut tut.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0)
 */

#include <gtk/gtk.h>


G_MODULE_EXPORT gboolean on_button1_clicked(
                GtkWidget      *event_box,
                            GdkEventButton *event,
                            gpointer     data)
{
    GtkImage *image;
    image = GTK_IMAGE(data);
    g_return_val_if_fail(image, FALSE);

    g_object_set(image, "file","/home/2.png", NULL);
    g_print ("Event box clicked at coordinates %f,%f\n",
             event->x, event->y);
    /* Returning TRUE means we handled the event, so the signal
     * emission should be stopped (don't call any further
     * callbacks that may be connected). Return FALSE
     * to continue invoking callbacks.
     */
    return TRUE;
}
int
main( int    argc,
      char **argv )
{
    GtkBuilder *builder;
    GtkWidget  *window;
    GtkWidget  *image;
    GError     *error = NULL;

    /* Init GTK+ */
    gtk_init( &argc, &argv );


    /* Create new GtkBuilder object */
    builder = gtk_builder_new();
    /* Load UI from file. If error occurs, report it and quit application.
     * Replace "tut.<b style="color:black;background-color:#ffff66">glade</b>" with your saved project. */
    if( ! gtk_builder_add_from_file( builder, "tut_3.xml", &error ) )
    {
        g_warning( "%s", error->message );
        g_free( error );
        return( 1 );
    }

    /* Get main window pointer from UI */
    GtkImage image = GTK_WIDGET(gtk_builder_get_object(builder, "image1"));

    /* Connect signals */
    gtk_builder_connect_signals( builder, data->image);

    /* Destroy builder, since we don't need it anymore */
    g_object_unref( G_OBJECT( builder ) );

    /* Show window. All other widgets are automatically shown by GtkBuilder */
    gtk_widget_show( data->window );

    /* Start main loop */
    gtk_main();

    return( 0 );
}

2 个答案:

答案 0 :(得分:3)

没有必要使用GtkEventBox来捕捉被点击的按钮 - 只需连接到GtkButton的“点击”信号。

以下是我认为您需要的代码版本。

/*
 * Compile me with:
 *   gcc -o tut tut.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0)
 */

#include <gtk/gtk.h>


G_MODULE_EXPORT gboolean on_button1_clicked(
                        GtkButton *button,
                        gpointer     data)
{
    GtkImage *image;
    image = GTK_IMAGE(data);
    g_return_val_if_fail(image, FALSE);

    g_object_set(image, "file","icon2.png", NULL);
    g_print ("Button clicked\n");
}
int
main( int    argc,
      char **argv )
{
    GtkBuilder *builder;
    GtkWidget  *window;
    GtkWidget  *image;
    GError     *error = NULL;

    /* Init GTK+ */
    gtk_init( &argc, &argv );


    /* Create new GtkBuilder object */
    builder = gtk_builder_new();
    /* Load UI from file. If error occurs, report it and quit application.
     * Replace "tut.<b style="color:black;background-color:#ffff66">glade</b>" with your saved project. */
    if( ! gtk_builder_add_from_file( builder, "tut_3.xml", &error ) )
    {
        g_warning( "%s", error->message );
        g_free( error );
        return( 1 );
    }

    /* Get main window pointer from UI */
    window = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
    image = GTK_WIDGET(gtk_builder_get_object(builder, "image1"));

    /* Connect signals */
    gtk_builder_connect_signals( builder, image);

    /* Destroy builder, since we don't need it anymore */
    g_object_unref( G_OBJECT( builder ) );

    /* Show window. All other widgets are automatically shown by GtkBuilder */
    gtk_widget_show( window );

    /* Start main loop */
    gtk_main();

    return( 0 );
}

这是相应的Glade文件:

<?xml version="1.0"?>
<interface>
  <requires lib="gtk+" version="2.16"/>
  <!-- interface-naming-policy project-wide -->
  <object class="GtkWindow" id="window1">
    <child>
      <object class="GtkButton" id="button1">
        <property name="label" translatable="yes">button</property>
        <property name="visible">True</property>
        <property name="can_focus">True</property>
        <property name="receives_default">True</property>
        <property name="image">image1</property>
        <signal name="clicked" handler="on_button1_clicked"/>
      </object>
    </child>
  </object>
  <object class="GtkImage" id="image1">
    <property name="visible">True</property>
    <property name="pixbuf">icon1.png</property>
  </object>
</interface>

要运行它,您需要在当前目录中放置两个文件,icon1.png和icon2.png。

PS。如果您不发布Glade文件,我无法确定您的代码到底在做什么。此外,你的代码甚至都没有编译,所以如果你确切地说了什么不起作用就会很好。

答案 1 :(得分:1)

要添加到ptomato的答案,gtk_object_set()应该有效,但这是一种迂回的做事方式。查看here以获得更普通的API调用,以使用磁盘文件的上下文替换现有GtkImage的内容。