如何解决如何从 GTK+ 程序调用程序,并分析程序的输出?
我正在编写一个粉碎文件的 GTK+ 前端程序。来自 GNU Coreutils 的程序 shred
是后端。编程语言是C。
所以,我有一个进度条显示完成了多少粉碎。但是,为了向用户提供有关切碎多少的准确数据,必须分析切碎的输出。
到目前为止,我已经尝试过 g_spawn_command_line_async
,但我无法将 shred 的输出发送到文件中。
解决方法
最简单的解决方案是使用 unix 重定向。您可以调用 system("shred -v file_to_shred > somefile.txt")
,输出将重定向到文件。然后,您可以使用 POSIX 读取或其他一些文件读取方法从文件中读取。在单独的线程中运行 system()
调用,并在主线程中逐步检查文件。您可以使用 POSIX sleep()
以某个时间间隔(例如每半秒)检查文件。但是,切勿在 GUI 线程上使用 sleep,因为这会冻结 UI。
这可以通过 GSubprocess(来自 GIO)实现。这是简化的源代码。 为此,您需要安装 gimp。 (它显示来自选项 --help 的帮助文本)
#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,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,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;
}
你就是这样做的。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。