我有这段代码:
#include <stdlib.h>
#include <gtk/gtk.h>
#include "splash_screen.h"
#include "db.h"
/* Global declarations */
GtkWidget *splash_window, *splash_image, *vbox, *pbar;
int timer;
/* A timeout to make the progressbar be animated */
static gboolean progress_timeout (gpointer data)
{
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (data));
/* Make this callback to be called again and again */
return TRUE;
}
/* A function to destroy the splash screen */
static void destroy_splash_screen (GtkWidget *window, int timer)
{
/* Finish the timer */
gtk_timeout_remove (timer);
timer = 0;
/* Destroy the widget window and its children */
gtk_widget_destroy (GTK_WIDGET (window));
}
/* Create the splash screen itself */
void splash_screen ()
{
/* The screen */
splash_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
/* The properties */
gtk_window_set_type_hint (GTK_WINDOW (splash_window), GDK_WINDOW_TYPE_HINT_SPLASHSCREEN);
gtk_window_set_decorated (GTK_WINDOW (splash_window), FALSE);
gtk_window_set_position (GTK_WINDOW (splash_window), GTK_WIN_POS_CENTER_ALWAYS);
gtk_window_set_default_size (GTK_WINDOW (splash_window), 300, 300);
gtk_window_set_resizable (GTK_WINDOW (splash_window), FALSE);
gtk_window_set_title (GTK_WINDOW (splash_window), "VadeTux [Cargando...]");
gtk_container_set_border_width (GTK_CONTAINER (splash_window), 0);
/* The splash image */
splash_image = gtk_image_new_from_file ("./imgs/splashscreen/end-splash.png");
/* The vertical box */
vbox = gtk_vbox_new (FALSE, 0);
/* Create the progress bar and make it pulse */
pbar = gtk_progress_bar_new ();
gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pbar));
/* The timer in charge of the animation */
timer = g_timeout_add (100, progress_timeout, pbar);
/* Start the packing */
gtk_container_add (GTK_CONTAINER (splash_window), vbox);
gtk_box_pack_start (GTK_BOX (vbox), splash_image, FALSE, FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), pbar, FALSE, FALSE, 0);
/* Show everything */
gtk_widget_show_all (splash_window);
get_page ("http://listadomedicamentos.aemps.gob.es/prescripcion.zip", "DB/prescripcion.zip");
destroy_splash_screen (splash_window, timer);
}
编辑:(大多数包含在我添加解压缩功能时)
#include <curl/curl.h>
#include <zip.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include "db.h"
void get_page (const char *url, const char *file_name)
{
CURL *easyhandle = curl_easy_init ();
curl_easy_setopt (easyhandle, CURLOPT_URL, url);
FILE *file = fopen (file_name, "w");
curl_easy_setopt (easyhandle, CURLOPT_WRITEDATA, file);
curl_easy_perform (easyhandle);
curl_easy_cleanup (easyhandle);
fclose (file);
}
计时器和destroy_splash_screen是运行良好的静态,get_page()是CURL函数。问题是,不是遵循(定义;创建窗口;绘制窗口;执行get_page;销毁窗口;)的顺序,而是(定义;创建窗口;执行get_page;绘制窗口;销毁窗口;)。 这样,下载过程中屏幕为空,窗口被破坏后才能看到任何内容。
我一直在四处寻找并且没有找到任何关于此的信息,我该如何修复它以便遵循我希望它的顺序?
答案 0 :(得分:1)
这是一个带有工作线程的Gtk +程序的几乎最小的例子。程序显示进度条并输入数字输入10秒钟。当工人完成时你可以做别的事情。但是,由于GTK +本身不是线程安全的,因此不应该从运行主循环的其他线程访问小部件。
#include <stdio.h>
#include <gtk/gtk.h>
gboolean stop_program(gpointer unused)
{
/* Idle function run in the main thread. */
gtk_main_loop();
return FALSE;
}
gpointer worker_func(gpointer unused)
{
/* This code runs in the worker thread. */
for (int i = 0; i < 10; ++i) {
printf("%d\n", i);
g_usleep(1000000);
}
g_idle_add(stop_program, NULL);
gtk_main_quit();
return NULL;
}
gboolean progress_cb(gpointer user_data)
{
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(user_data));
return TRUE;
}
int main(int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
GtkWidget *progress = gtk_progress_bar_new();
gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress));
guint timer = g_timeout_add (100, progress_cb, progress);
gtk_box_pack_start(GTK_BOX(box), progress, TRUE, TRUE, 6);
gtk_container_add(GTK_CONTAINER(window), box);
gtk_widget_show_all(window);
/* Start the worker thread before starting the main loop. */
GThread *thread = g_thread_new("worker thread", worker_func, NULL);
gtk_main();
/* Wait for the thread to finish. */
g_thread_join(thread);
return 0;
}