GTK+ Forums Forum Index GTK+ Forums
Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Execute command into a GtkTextView (C and Libglade)

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Example Code
Author Message
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 421
Location: Portland, OR USA

PostPosted: Fri Nov 30, 2007 9:39 pm    Post subject: Execute command into a GtkTextView (C and Libglade) Reply with quote

This is in response to a question I saw on Ubuntu Forums. Figured it'd be a good example. Shows how to use g_command_line_sync() to output a command into a GtkTextView.



main.c
Code: (C)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
Example running a command into a GtkTextView by Micah Carrick
Written for www.gtkforums.com
Compile using:
gcc -Wall -g main.c -o example `pkg-config --cflags --libs gtk+-2.0 libglade-2.0` 
*/

#include <gtk/gtk.h>
#include <glade/glade.h>

/* structure to hold references to our widgets */
typedef struct
{       
        GtkWidget               *entry;
        GtkWidget               *textview;
} MyWidgets;
               
/* call back function for when the button is pressed */
static void
on_execute_button_clicked (GtkWidget* widget, gpointer user_data)
{
        MyWidgets               *widgets;
        gchar                   *output;       
        const gchar             *command;       
        GError                  *error = NULL
        GtkTextBuffer           *buffer;
             
        widgets = (MyWidgets *)user_data;
        command = gtk_entry_get_text (GTK_ENTRY (widgets->entry));
       
        /* execute command */     
       
g_spawn_command_line_sync (command, &output, NULL, NULL, &error);
       
        if (error != NULL)
        {
                GtkWidget *dialog;
               
                /* create an error dialog containing the error message */
               
dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
                                                GTK_MESSAGE_ERROR,
                                                GTK_BUTTONS_OK,
                                                error->message);
                gtk_window_set_title (GTK_WINDOW (dialog), "Error");
               
                /* run the dialog */
               
gtk_dialog_run (GTK_DIALOG (dialog));
               
                /* clean up memory used by dialog and error */
               
gtk_widget_destroy (dialog);   
                g_error_free(error);
               
                return;
        }
       
        /* get the text buffer */
       
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widgets->textview));
       
        /* set the text in the buffer to the output */
       
gtk_text_buffer_set_text (buffer, output, -1);
       
        /* free the output string */
       
g_free (output);   
}

int
main (int argc, char *argv[])
{
       
        GtkWidget               *window;
        GladeXML                *gxml;
        MyWidgets               *widgets;
        PangoFontDescription    *font_desc;
       
        widgets = g_slice_new (MyWidgets);
       
        /* initialize the GTK+ library */
       
gtk_init (&argc, &argv);

        /* build GladeXML object from the glade XML file */
       
gxml = glade_xml_new ("example.glade", NULL, NULL);

        /* get widgets from GladeXML object */
       
window = glade_xml_get_widget (gxml, "window");
        widgets->entry = glade_xml_get_widget (gxml, "execute_entry");
        widgets->textview = glade_xml_get_widget (gxml, "output_textview");
       
        /* call gtk_main_quit() when the window's "x" is clicked */
       
glade_xml_signal_connect (gxml, "gtk_main_quit",
            G_CALLBACK (gtk_main_quit));

        /*
        Call on_button_clicked() when execute_button is clicked, passing the
        MyWidget struct to the function as the user_data
        */
       
glade_xml_signal_connect_data (gxml, "on_execute_button_clicked",
            G_CALLBACK (on_execute_button_clicked), widgets);

        /* free GladeXML object */
       
g_object_unref (G_OBJECT (gxml));
             
        /* use a fixed width font on the text view so the output looks proper */
       
       
font_desc = pango_font_description_from_string ("monospace 10");
        gtk_widget_modify_font (widgets->textview, font_desc);     
        pango_font_description_free (font_desc);     
             
        /* show the main window */
       
gtk_widget_show (window);

        gtk_main ();
       
        return 0;     
}



example.glade

Code: (XML/HTML)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
<!--Generated with glade3 3.4.0 on Fri Nov 30 13:06:29 2007 -->
<glade-interface>
  <widget
class="GtkWindow" id="window">
    <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
    <property
name="border_width">10</property>
    <signal
name="destroy" handler="gtk_main_quit"/>
    <child>
      <widget
class="GtkVBox" id="vbox1">
        <property
name="visible">True</property>
        <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
        <child>
          <widget
class="GtkHBox" id="hbox1">
            <property
name="visible">True</property>
            <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
            <property
name="spacing">5</property>
            <child>
              <widget
class="GtkEntry" id="execute_entry">
                <property
name="visible">True</property>
                <property
name="can_focus">True</property>
                <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
              </widget>
            </child>
            <child>
              <widget
class="GtkButton" id="execute_button">
                <property
name="visible">True</property>
                <property
name="can_focus">True</property>
                <property
name="receives_default">True</property>
                <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
                <property
name="label" translatable="yes">gtk-execute</property>
                <property
name="use_stock">True</property>
                <property
name="response_id">0</property>
                <signal
name="clicked" handler="on_execute_button_clicked"/>
              </widget>
              <packing>
                <property
name="expand">False</property>
                <property
name="position">1</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property
name="expand">False</property>
          </packing>
        </child>
        <child>
          <widget
class="GtkScrolledWindow" id="scrolledwindow1">
            <property
name="visible">True</property>
            <property
name="can_focus">True</property>
            <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
            <property
name="border_width">2</property>
            <property
name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
            <property
name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
            <property
name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
            <child>
              <widget
class="GtkTextView" id="output_textview">
                <property
name="visible">True</property>
                <property
name="can_focus">True</property>
                <property
name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
              </widget>
            </child>
          </widget>
          <packing>
            <property
name="position">1</property>
          </packing>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>
Back to top
gege2061



Joined: 04 Jan 2007
Posts: 3
Location: France

PostPosted: Fri Dec 07, 2007 8:58 am    Post subject: Reply with quote

Hello,

Some comments :
  • Why use Libglade and not new GtkBuilder Widget?
  • If command takes times, it's worth a better use g_spawn_command_line_async
Back to top
Micah Carrick
Never Seen the Sunlight


Joined: 21 Sep 2005
Posts: 421
Location: Portland, OR USA

PostPosted: Fri Dec 07, 2007 4:09 pm    Post subject: Reply with quote

Quote:
Why use Libglade and not new GtkBuilder Widget?


Because I have not yet learned anything about GtkBuilder, but it's on my TODO list. :)

Quote:
If command takes times, it's worth a better use g_spawn_command_line_async


Very true. I was just doing a very, very simple example. Readers will want to look over the Spawning Processes documentation.
Back to top
gege2061



Joined: 04 Jan 2007
Posts: 3
Location: France

PostPosted: Mon Dec 10, 2007 3:13 pm    Post subject: Reply with quote

Micah Carrick wrote:
Because I have not yet learned anything about GtkBuilder, but it's on my TODO list. :)

GtkBuilder is "juste" a libglade integration in GTK+.

First delete line 33 in example.glade (bug #496344) :
Code: (XML/HTML)
1
<property name="response_id">0</property>


Convert .glade file in GtkBuilder XML format :
Code: (Plaintext)
1
gtk-builder-convert example.glade example.xml


And remplace glade_* functions :
Code: (C)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
Example running a command into a GtkTextView by Micah Carrick
Written for www.gtkforums.com
Compile using:
gcc -Wall -g main.c -o example `pkg-config --cflags --libs gtk+-2.0 libglade-2.0`
*/

#include <gtk/gtk.h>

/* structure to hold references to our widgets */
typedef struct
{
        GtkWidget               *entry;
        GtkWidget               *textview;
} MyWidgets;

/* call back function for when the button is pressed */
static void
on_execute_button_clicked (GtkWidget* widget, gpointer user_data)
{
        MyWidgets               *widgets;
        gchar                   *output;
        const gchar             *command;
        GError                  *error = NULL;
        GtkTextBuffer           *buffer;

        widgets = (MyWidgets *)user_data;
        command = gtk_entry_get_text (GTK_ENTRY (widgets->entry));

        /* execute command */
       
g_spawn_command_line_sync (command, &output, NULL, NULL, &error);

        if (error != NULL)
        {
                GtkWidget *dialog;

                /* create an error dialog containing the error message */
               
dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT,
                                                GTK_MESSAGE_ERROR,
                                                GTK_BUTTONS_OK,
                                                error->message);
                gtk_window_set_title (GTK_WINDOW (dialog), "Error");

                /* run the dialog */
               
gtk_dialog_run (GTK_DIALOG (dialog));

                /* clean up memory used by dialog and error */
               
gtk_widget_destroy (dialog);
                g_error_free(error);

                return;
        }

        /* get the text buffer */
       
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widgets->textview));

        /* set the text in the buffer to the output */
       
gtk_text_buffer_set_text (buffer, output, -1);

        /* free the output string */
       
g_free (output);
}

int
main (int argc, char *argv[])
{

        GtkWidget               *window;
        GtkBuilder              *gxml;
        MyWidgets               *widgets;
        PangoFontDescription    *font_desc;

        widgets = g_slice_new (MyWidgets);

        /* initialize the GTK+ library */
       
gtk_init (&argc, &argv);

        /* build GladeXML object from the glade XML file */
       
gxml = gtk_builder_new ();
        gtk_builder_add_from_file (gxml, "example.xml", NULL);

        /* get widgets from GladeXML object */
       
window = GTK_WIDGET (gtk_builder_get_object (gxml, "window"));
        widgets->entry = GTK_WIDGET (gtk_builder_get_object (gxml, "execute_entry"));
        widgets->textview = GTK_WIDGET (gtk_builder_get_object (gxml, "output_textview"));

        /* call gtk_main_quit() when the window's "x" is clicked */
       
g_signal_connect (G_OBJECT (window), "delete-event", gtk_main_quit,
                          NULL);

        /*
        Call on_button_clicked() when execute_button is clicked, passing the
        MyWidget struct to the function as the user_data
        */
       
g_signal_connect (gtk_builder_get_object (gxml, "execute_button"),
                          "clicked", G_CALLBACK (on_execute_button_clicked),
                          widgets);

        /* free GladeXML object */
       
g_object_unref (G_OBJECT (gxml));

        /* use a fixed width font on the text view so the output looks proper */

       
font_desc = pango_font_description_from_string ("monospace 10");
        gtk_widget_modify_font (widgets->textview, font_desc);
        pango_font_description_free (font_desc);

        /* show the main window */
       
gtk_widget_show (window);

        gtk_main ();

        return 0;
}


;)
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Example Code All times are GMT
Page 1 of 1

 


Powered by phpBB © 2001, 2005 phpBB Group
CodeBB 1.0 Beta 2
Protected by Anti-Spam ACP