====== Scaricare un file dal web con Curl e Gtk3 ====== Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **// 26/09/2018 - 12:13 //** // // {{:programmazione:gtk:download_curl_gtk.png|}} **main.c** #include #include 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** 406 True False True True False vertical True True False True 0 True False Progresso True False True 2 True False Scarica un file dal web Usa lib curl per scaricare un file dal web. True True False gtk-execute True True True True False True 0