Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何从GTK+;调用程序;编程,并分析程序';谁的产量?_C_Command Line_Output_Analyzer_Gtk2 - Fatal编程技术网

C 如何从GTK+;调用程序;编程,并分析程序';谁的产量?

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”)并将输出重定向到该文件。

我正在写一个GTK+前端程序来分解文件。GNU Coreutils的程序
shread
是后端。编程语言是C

所以,我有一个进度条,显示有多少粉碎已经完成。但是,为了给用户提供有关粉碎量的准确数据,必须分析粉碎的输出


到目前为止,我已经尝试了
g\u spawn\u command\u line\u async
,但我无法将碎片的输出发送到文件。

最简单的解决方案是使用unix重定向。您可以调用
系统(“shred-v file\u to\u shred>somefile.txt”)
并将输出重定向到该文件。然后可以使用POSIX read或其他文件读取方法读取文件。在一个单独的线程中运行
system()
调用,然后在主线程中递增地检查文件。您可以使用POSIX
sleep()
每隔一段时间(比如每半秒)检查一次文件。但是,千万不要在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;
}