我在C中制作了一个GTK + 3应用程序,我想要一个微调器来显示程序何时处理数据。这是我通常拥有的:
main()
{
//Some statements
g_signal_connect(G_OBJECT(btnGenerate), "clicked", G_CALLBACK(Generate), &mainform);
}
void Generate(GtkWidget *btnGenerate, form_widgets *p_main_form)
{
gtk_spinner_start(GTK_SPINNER(p_main_form->spnProcessing));
Begin_Lengthy_Processing(Parameters, Galore, ...);
//gtk_spinner_stop(GTK_SPINNER(p_main_form->spnProcessing));
}
我已经注释了stop函数,所以即使在函数完成后我也可以看到微调器旋转,但是在函数完成后微调器STARTS,我怀疑它在主循环中打开。有没有办法让它启动并显示在回调函数内?我发现了同样的问题,但它使用了Python和线程。这是C,而不是python,所以我认为事情是不同的。
编辑:我也发现整个界面在执行长时间功能时冻结。
先谢谢。
答案 0 :(得分:1)
你需要在一个单独的线程中运行冗长的计算,或者将它分解成块并将它们分别作为主线程中的空闲回调分别运行。
如果您的冗长计算需要一组输入,并且在完成之前不需要任何其他输入,那么您应该将其构造为GTask
并使用g_task_run_in_thread()
来启动任务。其结果将通过GTask
的{{1}}传递回主线程。有一个例子here。
如果在进展过程中需要更多输入,您可能希望使用GAsyncQueue
为其提供更多输入,并使用GThreadPool
来提供线程(分摊通过多个调用创建线程的成本)延长功能,防止拒绝服务。)
GNOME开发人员文档提供overview of how to do threading。
答案 1 :(得分:0)
这就是我得到的:
int main()
{
// Statements...
g_signal_connect(G_OBJECT(btnGenerate), "clicked", G_CALLBACK(Process), &mainform);
// More statements...
}
void Process(GtkWidget *btnGenerate, form_widgets *p_main_form)
{
GError *processing_error;
GThread *start_processing;
gtk_spinner_start(GTK_SPINNER(p_main_form->spnProcessing));
active = true;
if((start_processing = g_thread_try_new(NULL, (GThreadFunc)Generate, p_main_form, &processing_error)) == NULL)
{
printf("%s\n", processing_error->message);
printf("Error, cannot create thread!?!?\n\n");
exit(processing_error->code);
}
}
void Generate(form_widgets *p_main_form)
{
// Long process
active = false;
}
我的程序,一旦清理完毕,因为程序中还有许多其他错误,将被放在GitHub上。
谢谢大家的帮助。这个答案来自于查看您的所有答案和评论,以及阅读更多文档,但主要是您的评论和答案。
答案 2 :(得分:-3)
我在gtk3程序中做了类似的事情。这并不困难。以下是我的意思。
{{1}}