Реализовано динамически настраиваемое количество строк ввода команд, отображение вывода команды в TextView (возможность копировать по ctrl+C, отсутствие необходимости запускать в терминале(если не нужно отображение ошибок))
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
GtkTextBuffer *buffer;
GtkWidget* vbox;
vector<string> getCommandParts(GtkWidget* hpaned1){
vector<string> vs;
GList* hpaned1List = gtk_container_get_children(GTK_CONTAINER( hpaned1 ));
for(int i=0;i<g_list_length(hpaned1List);i++){
GtkWidget* w1 = (GtkWidget* )g_list_nth_data(hpaned1List, i);
if(GTK_IS_ENTRY(w1)){
string s=gtk_entry_get_text(GTK_ENTRY(w1));
vs.push_back(s);
}else if(GTK_IS_HPANED(w1)){
GList* hpaned2List = gtk_container_get_children(GTK_CONTAINER( w1 ));
for(int i=0;i<g_list_length(hpaned2List);i++){
GtkWidget* w2 = (GtkWidget* )g_list_nth_data(hpaned2List, i);
if(GTK_IS_ENTRY(w2)){
string s=gtk_entry_get_text(GTK_ENTRY(w2));
vs.push_back(s);
}
}
}
}
return vs;
}
void buttonRunClicked(GtkWidget *widget, GtkWidget* hpaned1) {
vector<string> vs=getCommandParts( hpaned1 );
string s;
for(int i=0;i<vs.size();i++)
s+=vs[i];
FILE *f = popen(s.c_str(),"r");
if(!f)
return;
GtkTextIter iter;
gtk_text_buffer_get_iter_at_offset (buffer, &iter, 0);
gtk_text_buffer_insert (buffer, &iter, (string("##")+s+"\n").c_str(), -1);
int c;
string out;
while((c=fgetc(f))!=EOF){
out+=(char)c;
}
gtk_text_buffer_insert (buffer, &iter, out.c_str(), -1);
gtk_text_buffer_insert (buffer, &iter, "\n", -1);
pclose(f);
}
void buttonDelClicked(GtkWidget *widget, GtkWidget* hbox) {
gtk_widget_destroy(hbox);
}
void buttonCopyClicked(GtkWidget *widget, GtkWidget* hpaned1) {
GtkWidget* hbox = gtk_hbox_new(false, 0);
gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_box_reorder_child(GTK_BOX(vbox),hbox, 1);
GtkWidget *hpaned = gtk_hpaned_new ();
gtk_box_pack_start (GTK_BOX (hbox), hpaned, TRUE, TRUE, 0);
GtkWidget *entryRunB = gtk_entry_new ();
gtk_paned_add1 (GTK_PANED (hpaned), entryRunB);
GtkWidget *hpaned2 = gtk_hpaned_new ();
gtk_paned_add2 (GTK_PANED (hpaned), hpaned2);
GtkWidget *entryRun = gtk_entry_new ();
gtk_paned_add1 (GTK_PANED (hpaned2), entryRun);
GtkWidget *entryRunE = gtk_entry_new ();
gtk_paned_add2 (GTK_PANED (hpaned2), entryRunE);
if(hpaned1){
vector<string> vs=getCommandParts( hpaned1 );
gtk_entry_set_text(GTK_ENTRY(entryRunB),vs[0].c_str());
gtk_entry_set_text(GTK_ENTRY(entryRun),vs[1].c_str());
gtk_entry_set_text(GTK_ENTRY(entryRunE),vs[2].c_str());
}
GtkWidget* buttonRun = gtk_button_new_with_label("Run");
gtk_box_pack_start (GTK_BOX (hbox), buttonRun, FALSE, FALSE, 0);
g_signal_connect( G_OBJECT(buttonRun), "clicked", G_CALLBACK(buttonRunClicked), hpaned);
GtkWidget* buttonCopy = gtk_button_new_with_label("+");
gtk_box_pack_start (GTK_BOX (hbox), buttonCopy, FALSE, FALSE, 0);
g_signal_connect( G_OBJECT(buttonCopy), "clicked", G_CALLBACK(buttonCopyClicked), hpaned);
GtkWidget* buttonDel = gtk_button_new_with_label("-");
gtk_box_pack_start (GTK_BOX (hbox), buttonDel, FALSE, FALSE, 0);
g_signal_connect( G_OBJECT(buttonDel), "clicked", G_CALLBACK(buttonDelClicked), hbox);
gtk_widget_show_all(hbox);
}
int main(int argc, char** argv) {
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
vbox = gtk_vbox_new(false, 0);
gtk_container_add(GTK_CONTAINER(window), vbox);
GtkWidget* sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),GTK_POLICY_AUTOMATIC,GTK_POLICY_AUTOMATIC);
gtk_box_pack_end (GTK_BOX (vbox), sw, TRUE, TRUE, 0);
GtkWidget*view = gtk_text_view_new ();
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (view), GTK_WRAP_WORD);
gtk_container_add (GTK_CONTAINER (sw), view);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
buttonCopyClicked(0, 0);
g_signal_connect( G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit), 0);
gtk_widget_show_all(window);
gtk_main();
return 0;
}