C 如何从GTK+;调用程序;编程,并分析程序';谁的产量?
我正在写一个GTK+前端程序来分解文件。GNU Coreutils的程序C 如何从GTK+;调用程序;编程,并分析程序';谁的产量?,c,command-line,output,analyzer,gtk2,C,Command Line,Output,Analyzer,Gtk2,我正在写一个GTK+前端程序来分解文件。GNU Coreutils的程序shread是后端。编程语言是C 所以,我有一个进度条,显示有多少粉碎已经完成。但是,为了给用户提供有关粉碎量的准确数据,必须分析粉碎的输出 到目前为止,我已经尝试了g\u spawn\u command\u line\u async,但我无法将碎片的输出发送到文件。最简单的解决方案是使用unix重定向。您可以调用系统(“shred-v file\u to\u shred>somefile.txt”)并将输出重定向到该文件。
shread
是后端。编程语言是C
所以,我有一个进度条,显示有多少粉碎已经完成。但是,为了给用户提供有关粉碎量的准确数据,必须分析粉碎的输出
到目前为止,我已经尝试了
g\u spawn\u command\u line\u async
,但我无法将碎片的输出发送到文件。最简单的解决方案是使用unix重定向。您可以调用系统(“shred-v file\u to\u shred>somefile.txt”)
并将输出重定向到该文件。然后可以使用POSIX read或其他文件读取方法读取文件。在一个单独的线程中运行system()
调用,然后在主线程中递增地检查文件。您可以使用POSIXsleep()
每隔一段时间(比如每半秒)检查一次文件。但是,千万不要在GUI线程上使用睡眠,因为这会冻结UI。这可以通过GSubprocess(来自GIO)实现。下面是简化的源代码。
要使其工作,您需要安装gimp。(它显示选项--help中的帮助文本)
#包括
构造一切
{
GtkWidget*窗口;
GtkWidget*框;
GtkWidget*新的_工艺;
GtkWidget*gimp_帮助_标签;
};
单击新流程时无效(GtkWidget*wid,gpointer数据)
{
struct everything*wids=数据;
GError*error=NULL;/*这包含和可能由gio函数生成的错误*/
GInputStream*标准输出;
GSubprocess*过程;
gchar hello[10000];
process=g_subprocess_new(g_subprocess_FLAGS_STDOUT_PIPE,&error,“gimp”,“--help”,NULL);
标准输出=g_子流程(获取)标准输出(流程);;
g_输入_流_读取(标准输出、hello、9995、NULL和错误);
gtk_widget_hide(wids->new_process);/*隐藏按钮*/
wids->gimp_help_label=gtk_label_new(hello);/*创建一个新标签*/
gtk_-box_-pack_-start(gtk_-box(wids->box),wids->gimp_-help_-label,TRUE,TRUE,20);/*将其添加到框中*/
gtk_widget_show(wids->gimp_help_label);/*显示它*/
}
无效退出程序(GtkWidget*wid,gpointer数据)
{
gtk_main_quit();
}
int main(int argc,字符**argv)
{
gtk_init(&argc,&argv);
struct everything*widgets=(struct everything*)malloc(sizeof(struct everything));
widgets->window=gtk_window_new(gtk_window_顶级);
gtk_窗口设置默认大小(gtk_窗口(小部件->窗口),500500);
g_信号连接(小部件->窗口,“销毁”,g_回调(退出程序),空);
widgets->box=gtk_vbox_new(FALSE,0);
gtk_容器添加(gtk_容器(小部件->窗口)、小部件->框);
widgets->new_process=gtk_按钮_new_,带有_标签(“显示Gimp帮助”);
gtk_-box_-pack_-start(gtk_-box(widgets->box),widgets->new_-process,TRUE,TRUE,20);
g_信号连接(小部件->新建进程,“单击”,g_回调(新建进程上单击),小部件);
gtk_widget_show_all(widgets->window);
gtk_main();
返回0;
}
您就是这样做的。轮询会占用不必要的CPU时间,并耗尽用户的电池。最好将
g\u spawn\u async\u与管道一起使用()
@ptomoto fair point。我并不完全熟悉glib线程特性,我只是提供了一种使用POSIX标准的方法。实际上,运行一个单独的线程并在每个设置的时间间隔轮询不会太昂贵,因为线程大部分时间都处于睡眠状态。操作系统不会在休眠线程上浪费时间,因此只要使用合理的轮询间隔,使用的CPU时间量就最小。
#include <gtk/gtk.h>
struct everything
{
GtkWidget *window;
GtkWidget *box;
GtkWidget *new_process;
GtkWidget *gimp_help_label;
};
void on_new_process_clicked (GtkWidget *wid, gpointer data)
{
struct everything *wids = data;
GError *error = NULL; /* This contains and error that MAY be generated by the gio functions. */
GInputStream *stdout_output;
GSubprocess *process;
gchar hello[10000];
process = g_subprocess_new(G_SUBPROCESS_FLAGS_STDOUT_PIPE, &error, "gimp", "--help", NULL);
stdout_output = g_subprocess_get_stdout_pipe(process);
g_input_stream_read (stdout_output, hello, 9995, NULL, &error);
gtk_widget_hide(wids->new_process); /* Hide the button */
wids->gimp_help_label = gtk_label_new(hello); /* Make a new label. */
gtk_box_pack_start(GTK_BOX(wids->box), wids->gimp_help_label, TRUE, TRUE, 20); /* Add it to the box. */
gtk_widget_show(wids->gimp_help_label); /* Show it */
}
void exit_prog (GtkWidget *wid, gpointer data)
{
gtk_main_quit();
}
int main(int argc, char **argv)
{
gtk_init(&argc, &argv);
struct everything *widgets = (struct everything*)malloc(sizeof(struct everything));
widgets->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(widgets->window), 500, 500);
g_signal_connect(widgets->window, "destroy", G_CALLBACK(exit_prog), NULL);
widgets->box = gtk_vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(widgets->window), widgets->box);
widgets->new_process = gtk_button_new_with_label("Show Gimp Help");
gtk_box_pack_start(GTK_BOX(widgets->box), widgets->new_process, TRUE, TRUE, 20);
g_signal_connect(widgets->new_process, "clicked", G_CALLBACK(on_new_process_clicked), widgets);
gtk_widget_show_all(widgets->window);
gtk_main();
return 0;
}