Re: [DUDA] GTK+



Hola,

El mar, 12-02-2008 a las 23:24 -0300, Sebastian Gonzalez escribió:
> Hola:
> me llamo sebastian gonzalez, llevo un par de meses en todo esto del
> sofware libre y opensource, hace unos dias empeze a aprender GTK+ para
> tratar de contribuir, ya hago ventanas, botones, box, y todo lo
> basico. my pregunta es: como puedo utilizar la misma vetana al pasar a
> otra funcion?, ya que cuando paso a otra funcion tengo que hacer otra
> ventana

Puedes pasar la ventana como dato de usuario al callback de la señal que
estás conectando.

> 
> gtk_signal_connect(GTK_OBJECT(boton), "clicked",
> GTK_SIGNAL_FUNC(boton_funcion), NULL);

Esa llamada se transformaría en:

gtk_signal_connect(GTK_OBJECT(boton), "clicked",
                   GTK_SIGNAL_FUNC(boton_funcion), ventana);


Y tu callback se transformaría en:

void boton_funcion (GtkButton *button, gpointer data)
{
/* Transformar los datos de usuario en la ventana */
GtkWidget *ventana = GTK_WIDGET (data);

/* ahora puedes usar la misma ventana */


}

El problema que puedes tener ahora es que solo tienes acceso a la
ventana y no a los otros widgets que contiene. Si esto es un problema,
hay varias técnicas (en orden de dificultad):

1. Pasas como dato de tu callback solamente el widget sobre el cual
quieres actuar en el callback.
2. Si son múltiples widgets, puedes usar una estructura auxiliar, como

define struct MisDatos {
  GtkWidget *ventana;
  GtkWidget *etiquieta;
};

La instancias y llenas antes de conectar la señal:

  struct MisDatos datos = g_new0 (MisDatos, 1);

  datos->ventana = mi_ventana;
  datos->etiqueta = mi_etiqueta;

Y luego pasas esa instancia como dato de tu callback:

  gtk_signal_connect(GTK_OBJECT(boton), "clicked",
                     GTK_SIGNAL_FUNC(boton_funcion), datos);

Luego, en tu callback:

  boton_funcion (GtkButton *button, gpointer data) {
      GtkWidget *ventana, etiqueta;
      struct MisDatos *datos = (struct MisDatos *) data;
  
      ventana = datos->ventana;
      etiqueta = datos->etiqueta;

      /* Ya puedes jugar con los widgets */
  }


3. Puedes guardar un puntero a cada widget en el objeto ventana antes de
conectar el callback:

   g_object_set_data (G_OBJECT (ventana), "etiqueta", etiqueta);
   gtk_signal_connect (...);

Y luego obtienes esos datos desde el callback usando g_object_get_data,

4. Creas una clase heredada desde GtkWindow, la cual tenga como
propiedades todos los widgets que vas a usar en tu programa. Esto es un
poco más complejo, y no te lo recomiendo si estás recién aprendiendo.


Comentarios aparte, me da la impresión de que estás usando un tutorial
de GTK+ o una versión muy antigua de la documentación, porque parte del
código que usas está obsoleto. ¿De donde estás aprendiendo? ¿Qué versión
de GTK+ estás usando para programar?

Van a continuación algunos comentarios sobre tu programa:

> 
> De antemano, gracias.
> 
> PD: les mando el codigo para que entiendan lo que quiero hacer.
> 
> #include <gtk/gtk.h>
> 
> void boton_funcion();
> 
> int main (int argc, char * argv[]){
>      
>     GtkWidget *ventana, *boton, *etiqueta2;
>     GtkWidget *vbox;
>     
>     gtk_init(&argc, &argv);
>     
>     ventana=gtk_window_new(GTK_WINDOW_TOPLEVEL);
>     gtk_window_set_default_size(GTK_WINDOW(ventana), 200, 200);
                                  ^^^^^^^^^^^^^^^^^^
     Esta es la manera correcta de hacer un casting con GTK+/GObject.

>     boton=gtk_button_new_with_label("Boton");
>     etiqueta2=gtk_label_new("Presione el boton para tener otra
> ventana");
>     vbox=gtk_vbox_new(TRUE, 0);
>     gtk_box_pack_start((GtkBox *) vbox, etiqueta2, TRUE, TRUE, 0);
>     gtk_box_pack_start((GtkBox *) vbox, boton, TRUE, TRUE, 0);
                         ^^^^^^^^^^

      Esta es la manera incorrecta. Al igual que arriba, usa 

         GTK_BOX (vbox)

>     gtk_container_add(GTK_CONTAINER(ventana), vbox);
>     gtk_signal_connect(GTK_OBJECT(ventana), "delete_event",
> GTK_SIGNAL_FUNC(gtk_main_quit), NULL);

      gtk_signal_connect está obsoleta y ya no debe utilizarse. Lo
correcto es usar g_signal_connect:

      g_signal_connect (G_OBJECT (ventanan), "delete-event", 
                        G_CALLBACK (gtk_main_quit), NULL);


>     gtk_signal_connect(GTK_OBJECT(boton), "clicked",
> GTK_SIGNAL_FUNC(boton_funcion), NULL);
>     gtk_window_set_title(GTK_WINDOW(ventana), "Ventana");
>     gtk_widget_show_all(ventana);
>        gtk_main();
>     return 0; 
> }

> void boton_funcion(){
                   ^^^

        El prototipo de la función no es el apropiado. Si miras la
        documentación de GtkButton en
        
http://library.gnome.org/devel/gtk/stable/GtkButton.html#GtkButton-clicked

        verás que tu función callback debe tener la siguiente forma:
        
        void  user_function (GtkButton *button,
                     gpointer   user_data)      : Run First / Action

>     GtkWidget *etiketa, *boton, *ventana2;
>     
>     ventana2=gtk_window_new(GTK_WINDOW_TOPLEVEL);
>     etiketa=gtk_label_new("       Otra ventana mas        ");
>     gtk_container_add(GTK_CONTAINER(ventana2), etiketa);
>     gtk_window_set_title(GTK_WINDOW(ventana2), "boton_funcion");
>     gtk_widget_show_all(ventana2);
}

Saludos,

Claudio

-- 
Claudio Saavedra <csaavedra alumnos utalca cl>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]