2013-06-22 20 views
1

我想從Gnome/GTK產生一個新的應用程序到CLI應用程序,並將其輸出讀回到我的Gnome/GTK應用程序中。如何從Gnome/GTK產生一個新的應用程序到CLI應用程序並將其輸出讀回到Gnome/GTK應用程序?

的代碼按預期工作對於大多數shell命令,但與尾-f在/ var/log/messages中頂部沒有。有沒有什麼辦法解析這兩個命令的輸出?

正在運行Ubuntu 12.04.2 LTS和libgtk2.0。

#include <gtk/gtk.h> 

static GtkWidget *window;   // pointer to window 
static GtkWidget *view;   // pointer to textview 
static GtkTextBuffer *buffer;  // pointer to buffer 
static GtkTextIter iter;   // gtktextview iterator 
static GtkWidget *scrolled_window; // pointer to scrolled window 

FILE *fp;       // pointer to stdin/out file pipe 
char line[256];     // line read buffer size 

static gboolean on_delete_event (GtkWidget *widget, GdkEvent *event, gpointer data){ 
    gtk_main_quit(); 
    return FALSE; 
} 

void create_gui(){ 
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
    g_signal_connect (G_OBJECT (window), "delete_event", 
    G_CALLBACK(on_delete_event), NULL); 
    gtk_window_set_title (GTK_WINDOW (window), "GUI Front-End for CLI"); 

    GtkWidget *box = gtk_vbox_new(FALSE, 10);    // Create a box and 
    gtk_container_add (GTK_CONTAINER(window), box);   // set it as window's main child. 

    scrolled_window=gtk_scrolled_window_new(NULL, NULL);  // Now create scrolled window... 
    gtk_widget_set_usize(scrolled_window, 650, 450);   // Set scrolled window size.. 

    gtk_container_add(GTK_CONTAINER(box), scrolled_window); // Add scrolled window to vbox.. 
    view = gtk_text_view_new();        // Create textview.. 
    gtk_container_add(GTK_CONTAINER(scrolled_window), view); // Add textview to scrolled window.. 
    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); // Assign textview buffer 
    } 

void populate(){ 

fp = popen("cat /var/log/messages", "r");     // run shell command using pipe 

while (fgets(line, sizeof line, fp)){      // 
    gtk_text_buffer_get_end_iter (buffer, &iter);    
    gtk_text_buffer_insert (buffer, &iter, line, -1); 
} 
    pclose(fp);            // CLOSE Pipe 
} 

int main (int argc, char *argv[]){ 
    gtk_init (&argc, &argv); 
    create_gui(); 
    populate(); 
    gtk_widget_show_all (window); 
    gtk_main(); 
    return 0; 
} 

// TODO 
// fp = popen("ls -al", "r");   
// fp = popen("cat /proc/cpuinfo", "r");   
// fp = popen("cat /var/log/messages", "r");   
// fp = popen("lspci -v", "r");   
// fp = popen("w", "r");   
// fp = popen("last", "r");   
// fp = popen("pstree", "r");   

// fp = popen("tail -f /var/log/messages &", "r"); THIS DOES NOT WORK !  
// fp = popen("top", "r");       NEITHER DOES THIS.. 
enter code here 
+0

測試'wget'和'git clone'命令。大多數情況下,這兩個命令將打印文本到shell終端(從gnome-terminal運行您的gtk應用程序,您將看到命令輸出),而不是GtkTextView。我以前試過管道,但是,是的,只有一部分命令工具運行良好。 – LiuLang

+0

嗨劉謝謝你的幫助。讓我澄清我想做什麼。 例如: GTK應用程序調用「ls -a」,然後ls的輸出顯示在GTK_TEXTVIEW小部件中。 這是我能夠做的,但不是TOP或TAIL命令,這是我需要指導和幫助的地方。 非常感謝您的建議,我也會研究它們。 –

回答

1

toptail -f是長時間運行的程序(事實上,他們永遠不會退出),這樣你的閱讀整個輸出,並用它填充的textbuffer明顯的策略是行不通的。

相反,您需要創建一個IO通道,它監視管道正在發生的事情,將通道掛接到事件循環中,並在新輸出到達時將其附加到文本緩衝區。您的程序的簡約改變將重寫prepare函數,如下所示:

static gboolean data_ready(GIOChannel *channel, GIOCondition cond, gpointer data) 
{ 
    FILE *fp = data; 
    char line[256]; 

    if (fgets(line, sizeof line, fp)) { 
     gtk_text_buffer_get_end_iter (buffer, &iter);    
     gtk_text_buffer_insert (buffer, &iter, line, -1); 
     return TRUE; 
    } 
    else { 
     fclose(fp); 
     return FALSE; 
    } 
} 

void populate(){ 
    FILE *fp = popen("top -b", "r"); 
    GIOChannel *channel = g_io_channel_unix_new(fileno(fp)); 
    g_io_add_watch(channel, G_IO_IN, data_ready, fp); 
} 
+0

是的,我終於搞清楚了頂部和尾部--f永不退出。對於頂端,我想出了一個top -n1 -b的解決方法,但這不是我想要顯示的實時連續實時數據。 非常感謝代碼示例我對GIOChannel非常新,所以需要閱讀和教育我自己以及測試測試和測試,但是確保您的代碼能夠做我想做的事情,一旦我測試和驗證,就會做出正確的標記。再次非常感謝您花時間和您的指導,謝謝。 –

+1

@ArunaHewapathirane請注意,代碼被設計爲在沒有任何進一步修改的情況下放入您的程序中。事實上,這正是我對它的測試。 – user4815162342

相關問題