Autore: Fabio Di Matteo
Ultima revisione: 26/09/2018 - 12:13
main.c
#include <gtk/gtk.h> #include <curl/curl.h> GObject *btStart, *entry ; gdouble progress; //Questa funzione aggiorna la GtkProgressbar (viene ripetuta dal timeout) gboolean updateProgressbar(gpointer data) { g_print("UpdateProgressbar..."); if (progress>=0.1 && progress<=1.0) { gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR(data), progress); } if (progress>=1.0) { gtk_widget_set_sensitive(GTK_WIDGET(btStart), TRUE) ; gtk_progress_bar_set_text (GTK_PROGRESS_BAR(data),"Scaricamento terminato."); g_print("\n Stop updateProgressbar .\n"); return FALSE; } return TRUE; } //Questa callback scrive il file scaricato size_t writecallback(void *buffer, size_t size, size_t nmemb, void *stream){ int written = fwrite(buffer, size, nmemb, (FILE *)stream); return written; } //Questa callback scrive il progresso sulla variabile "progress" int progressDownload( void* ptr, double t, /* dltotal */ double d, /* dlnow */ double ultotal, double ulnow) { double percento= d*100/t; progress=percento/100; return 0; } //Funzione che viene avviata dal thread avvia il download void *Download(char *url) { g_print("Inside thread...\n"); CURL *curl; CURLcode res; char errbuf[CURL_ERROR_SIZE]; //long httpFail; curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writecallback); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L); curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, progressDownload); curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf); //curl_easy_setopt(curl, CURLOPT_FAILONERROR, httpFail); //gestione errori, da vedere char *outFile= g_path_get_basename (url); FILE *f = fopen(outFile,"wb"); if (f == NULL) { curl_easy_cleanup(curl); progress=1.0; } curl_easy_setopt(curl,CURLOPT_WRITEDATA, f); res = curl_easy_perform(curl); if(res != CURLE_OK) { progress=1.0; size_t len = strlen(errbuf); if(len) { g_print("Errore: %s\n", errbuf); } } //if (httpFail>=400) g_print("Problema http: %ld\n", httpFail); curl_easy_cleanup(curl); fclose(f); } } //Callback che crea lancia il thread void startThread (GtkWidget *widget, gpointer data) { progress=0; gchar* url =gtk_entry_get_text(GTK_ENTRY(entry)); g_timeout_add(1000, updateProgressbar, data); GThread *myThread; myThread= g_thread_new(NULL,(GThreadFunc)Download,url); gtk_widget_set_sensitive(widget, FALSE) ; gtk_progress_bar_set_text (GTK_PROGRESS_BAR(data),"Scaricamento in corso..."); } void on_mainWindow_delete_event(GtkWidget *widget, gpointer data) { gtk_main_quit(); } void mainWindowInit() { GError* error = NULL; gchar* glade_file = g_build_filename("gui.ui", NULL); GtkBuilder *xml; GObject *mainWindow, *progressBar, *lbl ; xml = gtk_builder_new (); if (!gtk_builder_add_from_file (xml, glade_file, &error)) { g_warning ("Couldn\'t load builder file: %s", error->message); g_error_free (error); } mainWindow=gtk_builder_get_object (xml,"mainWindow" ); btStart=gtk_builder_get_object (xml,"btStart" ); progressBar=gtk_builder_get_object(xml,"progressBar"); entry=gtk_builder_get_object(xml,"entry"); lbl=gtk_builder_get_object(xml,"lbl"); g_object_unref( G_OBJECT( xml ) ); g_signal_connect (mainWindow, "destroy", G_CALLBACK (on_mainWindow_delete_event), NULL); g_signal_connect (btStart, "clicked", G_CALLBACK (startThread),progressBar ); } int main (int argc, char **argv) { gtk_init (&argc, &argv); mainWindowInit(); gtk_main (); return 0; }
makefile
all: gcc main.c -o simple `pkg-config --cflags --libs gtk+-3.0 gthread-2.0 ` `curl-config --cflags --libs`
gui.ui
<?xml version="1.0" encoding="UTF-8"?> <!-- Generated with glade 3.20.0 --> <interface> <requires lib="gtk+" version="3.20"/> <object class="GtkWindow" id="mainWindow"> <property name="width_request">406</property> <property name="visible">True</property> <property name="can_focus">False</property> <property name="has_resize_grip">True</property> <signal name="delete-event" handler="on_mainWindow_delete_event()" swapped="no"/> <child> <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="orientation">vertical</property> <child> <object class="GtkEntry" id="entry"> <property name="visible">True</property> <property name="can_focus">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <placeholder/> </child> <child> <object class="GtkProgressBar" id="progressBar"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="text" translatable="yes">Progresso</property> <property name="show_text">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">2</property> </packing> </child> <child> <placeholder/> </child> </object> </child> <child type="titlebar"> <object class="GtkHeaderBar"> <property name="visible">True</property> <property name="can_focus">False</property> <property name="title">Scarica un file dal web</property> <property name="subtitle">Usa lib curl per scaricare un file dal web.</property> <property name="show_close_button">True</property> <child> <object class="GtkBox"> <property name="visible">True</property> <property name="can_focus">False</property> <child> <object class="GtkButton" id="btStart"> <property name="label">gtk-execute</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="use_stock">True</property> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> <property name="position">0</property> </packing> </child> <child> <placeholder/> </child> </object> </child> </object> </child> </object> </interface>
Il nostro wiki installa solamente cookie tecnici necessari al funzionamento della piattaforma "Dokuwiki". Niente analitics, statistiche, tracciamenti o altro.