entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

2votos

¿GTK C reemplazar el contenido de un widget vbox?

Hola, pues estoy empezando a trabajar con el GTK con C, sobre Windows y utilizando la ultima versión de GTK y Code::Blocks.

Pues quiero hacer una tarea de C con el GTK, tengo que trabajar varias pantallas de la aplicación, por así decirlo, tongo la pantalla principal, un login, barra de carga, etc.. lo que no se es como cambiar el contenido de la vbox, tengo un menu con el que cambiaría entre pantalla, entonces estaba pensando que con los CALL_BACKS podría destruir el widget que se muestra al comienzo y luego mostrar la siguiente pantalla, por ejemplo la barra de carga, pero el problema es que al hacerla visible la barra ya esta avanzando desde que se lanza la aplicación, por lo que ya estaba inicializado el widget, no he encontrado como crear el widget con un callback. Espero me puedan ayudar les dejo una captura de la pantalla principal de la app.

App GTK

0voto

burzumumbra comentado

Bueno acá dejo el código que tengo hasta el momento, aunque ya escogí la mejor respuesta y pues no porque fuera la única quiero dejar esto acá.

#include <gtk/gtk.h>
#include <stdio.h>
//!Barra de Progreso
static gfloat porcentaje = 0.0;
static gboolean progres_bar(gpointer data){
    porcentaje+=0.01;
    if(porcentaje >= 1.0){
        gtk_widget_destroy(data);
    }
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data),porcentaje);
}

static void barraP(gpointer caja){

//!Propiedades
    //!Barra
    barra = gtk_progress_bar_new();
    g_timeout_add(100,progres_bar,barra);
    gtk_progress_bar_set_show_text (barra,TRUE);
    gtk_box_pack_start(GTK_BOX(caja),barra, FALSE, FALSE, 0);
//!CALLBACKS
//!Mostrar WidGets
    gtk_widget_show(caja);
}
//!Main
int main(int argc, char *argv[]){
//!Variables
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *vbox_menu;
GtkWidget *vbox_contenido;
GtkWidget *etiqueta;
GtkWidget *frame;
GtkWidget *fecha;
GtkWidget *img;
//Menu
GtkWidget *menubar;
GtkWidget *filemenu;
GtkWidget *inicio;
GtkWidget *entrar;
GtkWidget *salir;
//Barra
GtkWidget *barra;
//Variables
time_t tiempo = time(0);
struct tm *tlocal = localtime(&tiempo);
char output[128];
strftime(output,128,"%d %B %Y %H:%M",tlocal);
char* TITULO = "Escuela de Danza";
char* SALUDO = "UNIVERSIDAD NACIONAL DE INGENIERIA\n\
                PROYECTO FORMATIVO 2\n\
                RONALD FLORES Carnet # \n\
                Nombre del Docente: ";
//!Inicializacion
gtk_init(&argc, &argv);
//!Propiedades
//!Ventana
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window),TITULO);
gtk_widget_set_size_request(window,400,300);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
//!VBOX
vbox = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show(vbox);
vbox_menu = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(vbox), vbox_menu);
gtk_box_pack_start(GTK_BOX(vbox),vbox_menu, FALSE, FALSE, 0);
gtk_widget_show(vbox_menu);
vbox_contenido = gtk_vbox_new(FALSE,0);
gtk_container_add(GTK_CONTAINER(vbox), vbox_contenido);
gtk_box_pack_start(GTK_BOX(vbox),vbox_contenido, FALSE, FALSE, 0);
gtk_widget_show(vbox_contenido);
//!Menu bar
menubar = gtk_menu_bar_new();
filemenu = gtk_menu_new();

inicio = gtk_menu_item_new_with_label("Inicio");
entrar = gtk_menu_item_new_with_label("Entrar");
salir = gtk_menu_item_new_with_label("Salir");
gtk_widget_show(inicio);
gtk_widget_show(entrar);
gtk_widget_show(salir);

gtk_menu_item_set_submenu(GTK_MENU_ITEM(inicio), filemenu);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), entrar);
gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), salir);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), inicio);
gtk_box_pack_start(GTK_BOX(vbox_menu), menubar,FALSE,TRUE,0);
gtk_widget_show(filemenu);
gtk_widget_show(menubar);
//!Imagen
img = gtk_image_new_from_file("uni.jpg");
gtk_box_pack_start(GTK_BOX(vbox_contenido),img,FALSE, TRUE, 0);
gtk_widget_show(img);
//!Etiqueta
etiqueta = gtk_label_new(SALUDO);
gtk_box_pack_start(GTK_BOX(vbox_contenido), etiqueta,TRUE,TRUE,0);
gtk_widget_show(etiqueta);
//!Frame
frame = gtk_frame_new("Fecha de entrega");
fecha = gtk_label_new(output);
gtk_container_add(GTK_CONTAINER(frame), fecha);
gtk_box_pack_start(GTK_BOX(vbox_contenido), frame,TRUE,FALSE,0);
gtk_widget_show(frame);
gtk_widget_show(fecha);
//!CALLBACKS
//!Window
g_signal_connect(window,"destroy", G_CALLBACK(gtk_main_quit), NULL);
//!Entrar - Barra
g_signal_connect_swapped(G_OBJECT(entrar), "activate",
    G_CALLBACK(gtk_widget_destroy),G_OBJECT(vbox_contenido));
g_signal_connect_swapped(G_OBJECT(entrar), "activate",
    G_CALLBACK(barraP),GTK_WIDGET(vbox_contenido));
//!Salir
g_signal_connect(G_OBJECT(salir), "activate",
    G_CALLBACK(gtk_main_quit), NULL);
//!Mostrar WidGets
gtk_widget_show(window);
gtk_main();
return 0;

}

1 Respuesta

3votos

white Puntos75880

define tus vistas primero, por ejemplo yo defino una vista con una barra de carga:

GtkWidget *progressbar;
static GtkWidget *view_1;
int current_view = 0;

static GtkWidget *
create_view_1 (void)
{
    GtkWidget *table = gtk_table_new (2, 2, TRUE);
    GtkAdjustment *adjustement;

    adjustement = (GtkAdjustment *) gtk_adjustment_new (50, 0, 100, 0, 0, 0);
    progressbar = gtk_progress_bar_new_with_adjustment (adj);
    gtk_table_attach_defaults (GTK_TABLE (table), progressbar, 0, 2, 1, 2);
    gtk_widget_show(progressbar);
    gtk_widget_show(table);

    return table;
}

int main (int argc, char *argv[])
{
     // .. inicializar GTK y crear la ventana principal antes

     view_1 = create_view_1();
}

podrias usar gtk_container_remove() y gtk_container_add() para agregar o eliminar los widgets del contenedor, la funcion para cambiar la vista podria ser (suponiendo que tengo 2 vistas definidas):

// changeView es un callback
// vbox es el widget contenedor
static void changeView (GtkWidget *wid, GtkWidget *win)
{

    gtk_container_remove (GTK_CONTAINER (vbox), current_view == 0 ? view0 : view1);
    g_object_ref (current_view == 0 ? view1 : view0);
    gtk_container_add (GTK_CONTAINER (vbox), current_view == 0 ? view1 : view0);

    current_view = (current_view == 0 ? 1 : 0);
}

podrias agregar tu codigo? asi podremos guiarte con lo que ya tienes escrito, asi puedo saber tambien como carga tu barra de progreso escrita.

0voto

burzumumbra comentado

Gracias, hoy mismo lo ensayo, y agradezco en especial, tomando en cuenta que olvide agregar el código que tengo ¬¬ pero creo que es la mejor respuesta que he conseguido al respecto, no se me hubiera ocurrido hacer eso con las vistas; por cierto es muy difícil encontrar un buen tutorial completo de GTK, solo como utilizar los elementos por separados y pues nada avanzado, solo queda usar un poco mas la cabeza.

Movido a comentario: no es otra respuesta a la pregunta.

0voto

burzumumbra comentado

Ya en un rato pongo lo que tengo de código, pero creo que tu respuesta me va solucionar mi problema.

Movido a comentario: no es otra respuesta a la pregunta.

0voto

burzumumbra comentado

hola estaba siguiendo tus recomendaciones, pero no entiendo muy bien la parte del cambio de vistas, disculpa la molestia, te dejo lo que tengo de código.

#include <gtk/gtk.h>
#include <stdio.h>
static GtkWidget *pantalla_0;
static GtkWidget *pantalla_1;
static GtkWidget *pantalla_2;
int current_view = 0;

//!Barra de Progreso
static gfloat porcentaje = 0.0;
static gboolean progres_bar(gpointer data){
    porcentaje+=0.01;
    if(porcentaje >= 1.0){
        gtk_widget_destroy(data);
    }
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data),porcentaje);
}

static GtkWidget *
create_view_0 (void){
    GtkWidget *vbox_conte = gtk_vbox_new(FALSE,0);
    GtkWidget *etiqueta;
    GtkWidget *frame;
    GtkWidget *fecha;
    GtkWidget *img;
    //Non GTK
    time_t tiempo = time(0);
    struct tm *tlocal = localtime(&tiempo);
    char output[128];
    strftime(output,128,"%d %B %Y %H:%M",tlocal);
    char* SALUDO = "UNIVERSIDAD NACIONAL DE INGENIERIA\n\
                    PROYECTO FORMATIVO 2\n\
                    RONALD FLORES Carnet # 2014-1174U\n\
                    Nombre del Docente: ";
    //!Imagen
    img = gtk_image_new_from_file("uni.jpg");
    gtk_box_pack_start(GTK_BOX(vbox_conte),img,FALSE, TRUE, 0);
    gtk_widget_show(img);
    //!Etiqueta
    etiqueta = gtk_label_new(SALUDO);
    gtk_box_pack_start(GTK_BOX(vbox_conte), etiqueta,TRUE,TRUE,0);
    gtk_widget_show(etiqueta);
    //!Frame
    frame = gtk_frame_new("Fecha de entrega");
    fecha = gtk_label_new(output);
    gtk_container_add(GTK_CONTAINER(frame), fecha);
    gtk_box_pack_start(GTK_BOX(vbox_conte), frame,TRUE,FALSE,0);
    gtk_widget_show(frame);
    gtk_widget_show(fecha);

    gtk_widget_show(vbox_conte);

    return vbox_conte;
}

static GtkWidget *
create_view_2 (void){
    GtkWidget *vbox_conte = gtk_vbox_new(FALSE,0);
    GtkWidget *barra;
    GtkWidget *continuar;
    barra = gtk_progress_bar_new();
    g_timeout_add(100,progres_bar,barra);
    gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR(barra),TRUE);
    gtk_box_pack_start(GTK_BOX(vbox_conte),barra, FALSE, FALSE, 0);
    continuar = gtk_button_new_with_label("Continuar..");
    gtk_box_pack_start(GTK_BOX(vbox_conte),continuar, FALSE, FALSE, 0);
    gtk_widget_show(barra);
    gtk_widget_show(vbox_conte);
    g_signal_connect_swapped(G_OBJECT(barra), "destroy",
        G_CALLBACK(gtk_widget_show),G_OBJECT(continuar));
    return vbox_conte;
}

static GtkWidget *
create_view_3 (void){
    GtkWidget *vbox_conte = gtk_vbox_new(FALSE,0);

    gtk_widget_show(vbox_conte);

    return vbox_conte;
}

int main(int argc, char *argv[]){
    //Ventana
    GtkWidget *window;
    //Menu Items
    GtkWidget *menubar;
    GtkWidget *filemenu;
    GtkWidget *inicio;
    GtkWidget *entrar;
    GtkWidget *salir;
    //Contenedores
    GtkWidget *vbox;//Contenedor principal
    GtkWidget *vbox_menu;//Contenedor Menu
    GtkWidget *vbox_contenido;//Cuerpo contenedor actualizable
    //Non GTK
    char* TITULO = "Escuela de Danza";
    //!Inicializacion
    gtk_init(&argc, &argv);
    //!Propiedades
    //Ventana
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window),TITULO);
    gtk_widget_set_size_request(window,400,300);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
    //VBOX
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_container_add(GTK_CONTAINER(window), vbox);
    vbox_menu = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(vbox), vbox_menu);
    gtk_box_pack_start(GTK_BOX(vbox),vbox_menu, FALSE, FALSE, 0);
    vbox_contenido = gtk_vbox_new(FALSE,0);
    gtk_container_add(GTK_CONTAINER(vbox), vbox_contenido);
    gtk_box_pack_start(GTK_BOX(vbox),vbox_contenido, FALSE, FALSE, 0);
    //!Container actualizable.
    gtk_container_add(GTK_CONTAINER(vbox_contenido), create_view_0());
    //Menu bar
    menubar = gtk_menu_bar_new();
    filemenu = gtk_menu_new();

    inicio = gtk_menu_item_new_with_label("Inicio");
    entrar = gtk_menu_item_new_with_label("Entrar");
    salir = gtk_menu_item_new_with_label("Salir");

    gtk_menu_item_set_submenu(GTK_MENU_ITEM(inicio), filemenu);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), entrar);
    gtk_menu_shell_append(GTK_MENU_SHELL(filemenu), salir);
    gtk_menu_shell_append(GTK_MENU_SHELL(menubar), inicio);
    gtk_box_pack_start(GTK_BOX(vbox_menu), menubar,FALSE,TRUE,0);
    //Contenedor
    //gtk_container_add(contenedor,vbox);
    //!gtk_widget_show();
    gtk_widget_show(window);
    gtk_widget_show(vbox);
    gtk_widget_show(vbox_menu);
    gtk_widget_show(vbox_contenido);
    gtk_widget_show(filemenu);
    gtk_widget_show(menubar);
    gtk_widget_show(inicio);
    gtk_widget_show(entrar);
    gtk_widget_show(salir);
    //!CALLBACKS
    //Window
    g_signal_connect(window,"destroy", G_CALLBACK(gtk_main_quit), NULL);
    //Salir
    g_signal_connect(G_OBJECT(salir), "activate",
        G_CALLBACK(gtk_main_quit), NULL);
    gtk_main();
    return 0;
}

0voto

white comentado

Escribí un codigo de volada, trate de poner algo de tu codigo para darte el ejemplo, le falta que el cambio de vista sea mas dinamico ( TODO: tener un struct con las vistas con key, contenido y un booleano para ver si esta seleccionada), no me fije en el performance, pero la idea está.

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

typedef enum {
    EMPTY_VIEW = 0,
    HOME_VIEW = 1,
    LOADING_VIEW = 2,
    LOGIN_VIEW = 3
} APP_VIEW;

typedef struct{
    GtkWidget *home;
    GtkWidget *loading;
    GtkWidget *login;
} typeAppViews;

typeAppViews *appViews = NULL;

APP_VIEW current_view = EMPTY_VIEW;
GtkWidget *vbox;

//!Barra de Progreso
static gfloat porcentaje = 0.0;
static gboolean progres_bar(gpointer data){
    porcentaje+=0.01;
    if(porcentaje >= 1.0){
        gtk_widget_destroy(data);
    }
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(data),porcentaje);
}

static GtkWidget *
createHomeView (void)
{
    GtkWidget *scrolled_window = NULL;
    char* SALUDO = "UNIVERSIDAD NACIONAL DE INGENIERIA\n\
                    PROYECTO FORMATIVO 2\n\
                    RONALD FLORES Carnet # 2014-1174U\n\
                    Nombre del Docente: ";

    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
    GtkWidget *view1_content = gtk_label_new (SALUDO);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW
                     (scrolled_window), view1_content);
    gtk_widget_show_all (scrolled_window);

    return scrolled_window;
}

static GtkWidget *
createLoadingView (void)
{
    GtkWidget *vbox_conte = gtk_vbox_new(FALSE,0);
    GtkWidget *barra;
    GtkWidget *continuar;
    barra = gtk_progress_bar_new();
    g_timeout_add(100,progres_bar,barra);
    gtk_box_pack_start(GTK_BOX(vbox_conte),barra, FALSE, FALSE, 0);
    continuar = gtk_button_new_with_label("Continuar..");
    gtk_box_pack_start(GTK_BOX(vbox_conte),continuar, FALSE, FALSE, 0);
    gtk_widget_show(barra);
    gtk_widget_show(vbox_conte);
    g_signal_connect_swapped(G_OBJECT(barra), "destroy",
        G_CALLBACK(gtk_widget_show),G_OBJECT(continuar));

    return vbox_conte;
}

static GtkWidget *
createLoginView ()
{
    GtkWidget *content = gtk_vbox_new(FALSE,0);
    GtkWidget *label = gtk_label_new ("aca va el login...");
    gtk_box_pack_start(GTK_BOX(content), label, FALSE, FALSE, 0);
    gtk_widget_show(content);
    gtk_widget_show(label);

    return content;
}

static void changeView( gchar *string )
{
    printf ("'%s'\n", string);
    APP_VIEW view;

    if(strcmp( string, "Inicio") == 0)
        view = HOME_VIEW;

    else if(strcmp( string, "Entrar") == 0)
        view = LOGIN_VIEW;

    // solo de prueba...
    else if(strcmp( string, "Cargar") == 0)
        view = LOADING_VIEW;

    if(view == current_view)
        return;

    if( appViews->home == NULL )
        appViews->home = createHomeView();

    printf("cambiando vista\n");

    gtk_container_remove(GTK_CONTAINER(vbox), appViews->loading);
    gtk_container_remove(GTK_CONTAINER(vbox), appViews->login);
    gtk_container_remove(GTK_CONTAINER(vbox), appViews->home);

    switch(view)
    {
        case HOME_VIEW:

            appViews->home = createHomeView();

            gtk_container_add(GTK_CONTAINER(vbox), appViews->home);

        break;

        case LOGIN_VIEW:

            appViews->login = createLoginView();

            gtk_container_add(GTK_CONTAINER(vbox), appViews->login);

        break;

        case LOADING_VIEW:

            appViews->loading = createLoadingView();

            gtk_container_add(GTK_CONTAINER(vbox), appViews->loading);
        break;
    };

    current_view = view;
}

int main (int argc, char *argv[])
{
    GtkWidget *window;
    GtkWidget *menu;
    GtkWidget *menu_bar;
    GtkWidget *root_menu;

    appViews = g_malloc (sizeof(typeAppViews));

    g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
    gtk_init (&argc, &argv);
    g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 8);
    gtk_window_set_title (GTK_WINDOW (window), "Escuela de danza");
    gtk_widget_set_size_request(window,400,300);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_resizable(GTK_WINDOW(window),FALSE);
    gtk_widget_realize (window);
    g_signal_connect (window, "destroy", gtk_main_quit, NULL);

    vbox = gtk_vbox_new (FALSE, 0);
    gtk_container_add (GTK_CONTAINER (window), vbox);
    gtk_widget_show (vbox);

    /* construimos el menu */

    // si estas en ubuntu (unity) como yo :P entonces este fix es de ayuda
    g_object_set(gtk_settings_get_default(), "gtk-shell-shows-menubar", FALSE, NULL);

    // definimos el menu
    menu = gtk_menu_new();
    GtkWidget *menu_item;
    char *menu_labelitems[] = {
        "Inicio",
        "Entrar",
        "Cargar",
        "Salir"
    };
    int total_items = sizeof(menu_labelitems) / sizeof(menu_labelitems[0]);
    int i; // C 99 ? duh :/

    for(i = 0; i <= total_items-1; i++)
    {
        // creamos el item con un label
        menu_item = gtk_menu_item_new_with_label (menu_labelitems[i]);

        // agregamos al menu el item
        gtk_menu_append (GTK_MENU (menu), menu_item);

        // creamos un evento para el item

        // si el item es el de "Salir" agregamos un evento para salir del programa
        if(menu_labelitems[i] == "Salir")
        {
            gtk_signal_connect_object (GTK_OBJECT (menu_item), "activate",
                    GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
        }
        // sino..
        else
        {
            gtk_signal_connect_object (GTK_OBJECT (menu_item), "activate",
                    GTK_SIGNAL_FUNC (changeView), (gpointer) g_strdup (menu_labelitems[i]));
        }

        //mostramos el item
        gtk_widget_show (menu_item);
    }

    root_menu = gtk_menu_item_new_with_label ("Ir a");
    gtk_widget_show (root_menu);
    gtk_menu_item_set_submenu (GTK_MENU_ITEM (root_menu), menu);

    menu_bar = gtk_menu_bar_new ();
    gtk_box_pack_start (GTK_BOX (vbox), menu_bar, FALSE, FALSE, 2);
    gtk_widget_show (menu_bar);

    gtk_menu_bar_append (GTK_MENU_BAR (menu_bar), root_menu);

    /* agregamos la vista por default al contenedor */
    changeView("Inicio");

    /* main loop */
    gtk_widget_show_all (window);
    gtk_main ();
    return 0;
}

0voto

burzumumbra comentado

Voy a intentarlo, por cierto, en el código que me das estas usando funciones de Gtk 2 verdad?

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta