Re: Show dialog after hide another




Hi Ruben,

You can give the following a try and see if it helps. Basically you don't want to bind up the "main" thread 
with a long running function and freeze your UI. 

Eric

/* 
  gcc -Wall firmware1.c -o firmware1 `pkg-config --cflags --libs gtk+-3.0`
  Tested on Ubuntu16.04 and GTK3.18
*/

#include<gtk/gtk.h>

/*
  Set some numbers for work to be done in the worker thread. Might need to change
  these for a faster cpu but be careful of guint overflow.
*/
#define SET1 1000000000
#define SET2 100000000

static guint timeout_id=0;
static gint thread_active=0;
static gint load_progress=0;
static GThread *thread=NULL;

static void start_thread(GtkWidget *widget, GtkWidget **widgets);
static gpointer thread_get_firmware(GtkWidget **widgets);
static gboolean thread_join(GtkWidget **widgets);
static gboolean check_progress(GtkWidget *progress);
static void show_dialog(GtkWidget *widget, GtkWidget *window);

int main(int argc, char *argv[])
  {
    gtk_init(&argc, &argv);

    GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Show Progress");
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_window_set_default_size(GTK_WINDOW(window), 300, 100);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *progress=gtk_progress_bar_new();
    gtk_widget_set_hexpand(progress, TRUE);
    gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(progress), TRUE);

    GtkWidget *button1=gtk_button_new_with_label("Show Firmware Progress");
    gtk_widget_set_hexpand(button1, TRUE);
    //Some widgets to pass through the thread function to g_idle_add(). 
    GtkWidget *widgets[]={progress, button1};
    g_signal_connect(button1, "clicked", G_CALLBACK(start_thread), widgets);

    GtkWidget *button2=gtk_button_new_with_label("Show a Dialog");
    gtk_widget_set_hexpand(button2, TRUE);
    g_signal_connect(button2, "clicked", G_CALLBACK(show_dialog), window);

    GtkWidget *grid=gtk_grid_new();
    gtk_grid_attach(GTK_GRID(grid), button1, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), progress, 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), button2, 0, 2, 1, 1);
    gtk_container_add(GTK_CONTAINER(window), grid);
   
    gtk_widget_show_all(window);
    
    gtk_main();
    return 0;   
  }
static void start_thread(GtkWidget *widget, GtkWidget **widgets)
  {  
    gtk_widget_set_sensitive(widget, FALSE); 
    g_atomic_int_set(&thread_active, 1);
    
    thread=g_thread_new("TestThread", (GThreadFunc)thread_get_firmware, widgets);   
    timeout_id=g_timeout_add(500, (GSourceFunc)check_progress, widgets[0]);     
  }
static gpointer thread_get_firmware(GtkWidget **widgets)
  {
    //No GTK functions called in thread_get_firmware().
    guint32 i=0;
    gdouble percent=0;    
    
    for(i=0;i<SET1;i++)
      {
        if(i%SET2==0)
          {
            percent=(gdouble)(i+1)/SET1;
            g_atomic_int_set(&load_progress, (gint)(percent*100));
          }
      }
    
    g_atomic_int_set(&thread_active, 0); 
    
    g_idle_add((GSourceFunc)thread_join, widgets);
    return NULL;    
  }
static gboolean thread_join(GtkWidget **widgets)
  {
    if(thread!=NULL)
      {
         g_print("Thread Join\n");
         g_thread_join(thread);
         thread=NULL;
       }

    //Update widgets.
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(widgets[0]), 0);
    gchar *string=g_strdup_printf("progress %i%%", 0);
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(widgets[0]), string);
    g_free(string);
    gtk_widget_set_sensitive(widgets[1], TRUE); 
    g_atomic_int_set(&load_progress, 0);

    return FALSE;
  }
static gboolean check_progress(GtkWidget *progress)
  {
    gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress), 
(gdouble)(g_atomic_int_get(&load_progress)/100.0));
    gchar *string=g_strdup_printf("progress %i%%", g_atomic_int_get(&load_progress));
    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(progress), string);
    g_free(string);
  
    if(g_atomic_int_get(&thread_active)==1)
      {
        return TRUE;
      }
    else
      {
        timeout_id=0;
        return FALSE;
      }
  }
static void show_dialog(GtkWidget *widget, GtkWidget *window)
  {
    GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, 
GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Message Dialog");
    gtk_dialog_run(GTK_DIALOG(dialog));
    gtk_widget_destroy(dialog);
  }


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