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 

Connecting widgets to signals

 
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming
Author Message
gallen
Familiar Face


Joined: 01 Sep 2007
Posts: 10

PostPosted: Sat Sep 15, 2007 7:44 am    Post subject: Connecting widgets to signals Reply with quote

Hi everyone,

Firstly I'm writing in C.

I'm trying to create my own signal to emit which will be connected to some widgets (Drawing areas).
Basically what I want to happen is: when the state of a variable changes I will emit a signal which will be caught by many different widgets, each of which will supply their own callback functions.

I've found: http://le-hacker.org/papers/gobject/ch05s03.html
which gives an introduction to signals, but I am finding it very difficult to understand what to do.

All i want is to create a signal, then connect widgets to that signal. If anyone can give me some skeleton code to do this that would be fantastic.

Also, I noticed the g_signal_emit() function's first argument asks for an instance to emit the signal on. Can't you just generically emit a signal and let whoever is connected to the signal handle it themselves?

Thanks,

Glenn
Back to top
caracal
GTK+ Geek


Joined: 21 Jun 2007
Posts: 91
Location: Wilkes Barre Pa

PostPosted: Sat Sep 15, 2007 8:46 am    Post subject: Reply with quote

scribble-simple.c

Code: (Plaintext)
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183


/* GTK - The GIMP Toolkit
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

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

/* Backing pixmap for drawing area */
static GdkPixmap *pixmap = NULL;

/* Create a new backing pixmap of the appropriate size */
static gboolean configure_event( GtkWidget         *widget,
                                 GdkEventConfigure *event )
{
  if (pixmap)
    g_object_unref (pixmap);

  pixmap = gdk_pixmap_new (widget->window,
               widget->allocation.width,
               widget->allocation.height,
               -1);
  gdk_draw_rectangle (pixmap,
              widget->style->white_gc,
              TRUE,
              0, 0,
              widget->allocation.width,
              widget->allocation.height);

  return TRUE;
}

/* Redraw the screen from the backing pixmap */
static gboolean expose_event( GtkWidget      *widget,
                              GdkEventExpose *event )
{
  gdk_draw_drawable (widget->window,
             widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
             pixmap,
             event->area.x, event->area.y,
             event->area.x, event->area.y,
             event->area.width, event->area.height);

  return FALSE;
}

/* Draw a rectangle on the screen */
static void draw_brush( GtkWidget *widget,
                        gdouble    x,
                        gdouble    y)
{
  GdkRectangle update_rect;

  update_rect.x = x - 5;
  update_rect.y = y - 5;
  update_rect.width = 10;
  update_rect.height = 10;
  gdk_draw_rectangle (pixmap,
              widget->style->black_gc,
              TRUE,
              update_rect.x, update_rect.y,
              update_rect.width, update_rect.height);
  gtk_widget_queue_draw_area (widget,
                      update_rect.x, update_rect.y,
                      update_rect.width, update_rect.height);
}

static gboolean button_press_event( GtkWidget      *widget,
                                    GdkEventButton *event )
{
  if (event->button == 1 && pixmap != NULL)
    draw_brush (widget, event->x, event->y);

  return TRUE;
}

static gboolean motion_notify_event( GtkWidget *widget,
                                     GdkEventMotion *event )
{
  int x, y;
  GdkModifierType state;

  if (event->is_hint)
    gdk_window_get_pointer (event->window, &x, &y, &state);
  else
    {
      x = event->x;
      y = event->y;
      state = event->state;
    }
   
  if (state & GDK_BUTTON1_MASK && pixmap != NULL)
    draw_brush (widget, x, y);
 
  return TRUE;
}

void quit ()
{
  exit (0);
}

int main( int   argc,
          char *argv[] )
{
  GtkWidget *window;
  GtkWidget *drawing_area;
  GtkWidget *vbox;

  GtkWidget *button;

  gtk_init (&argc, &argv);

  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_name (window, "Test Input");

  vbox = gtk_vbox_new (FALSE, 0);
  gtk_container_add (GTK_CONTAINER (window), vbox);
  gtk_widget_show (vbox);

  g_signal_connect (G_OBJECT (window), "destroy",
                    G_CALLBACK (quit), NULL);

  /* Create the drawing area */

  drawing_area = gtk_drawing_area_new ();
  gtk_widget_set_size_request (GTK_WIDGET (drawing_area), 200, 200);
  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);

  gtk_widget_show (drawing_area);

  /* Signals used to handle backing pixmap */

  g_signal_connect (G_OBJECT (drawing_area), "expose_event",
            G_CALLBACK (expose_event), NULL);
  g_signal_connect (G_OBJECT (drawing_area),"configure_event",
            G_CALLBACK (configure_event), NULL);

  /* Event signals */

  g_signal_connect (G_OBJECT (drawing_area), "motion_notify_event",
            G_CALLBACK (motion_notify_event), NULL);
  g_signal_connect (G_OBJECT (drawing_area), "button_press_event",
            G_CALLBACK (button_press_event), NULL);

  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
             | GDK_LEAVE_NOTIFY_MASK
             | GDK_BUTTON_PRESS_MASK
             | GDK_POINTER_MOTION_MASK
             | GDK_POINTER_MOTION_HINT_MASK);

  /* .. And a quit button */
  button = gtk_button_new_with_label ("Quit");
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);

  g_signal_connect_swapped (G_OBJECT (button), "clicked",
                G_CALLBACK (gtk_widget_destroy),
                G_OBJECT (window));
  gtk_widget_show (button);

  gtk_widget_show (window);

  gtk_main ();

  return 0;
}


Look at the code before int main( int argc,
char *argv[] )
{

Then look at the code after. Do you see the g_signal_connect,s which ones belong to which
section of code above int main( int argc,
char *argv[] )
{

When learning gtk it best to take they examples in the example dir in the gtk source package
open one up like this one above and open a tutorial and the api doc on the gtk web site now if you don't understand a piece of code you read the api for say g_signal_connect in order to get a better idea of what it can do then go threw the tutorials and find sections that relate to
g_signal_connect and read very carefully about how there used.

Here is a list of tutorial
http://www.gtkforums.com/viewtopic.php?t=769

Gtk api see here http://library.gnome.org/devel/references

Make sure you have a good code editor like scite http://www.scintilla.org/SciTE.html
it will make code easer to read etc.
Back to top
gallen
Familiar Face


Joined: 01 Sep 2007
Posts: 10

PostPosted: Sun Sep 16, 2007 2:25 am    Post subject: Reply with quote

Great, thanks for that! Those tutorials and examples folder will probably help a lot, I'm sorry I'm very unfamiliar with Linux atm and I get lost a little while searching, so thanks again.
Back to top
caracal
GTK+ Geek


Joined: 21 Jun 2007
Posts: 91
Location: Wilkes Barre Pa

PostPosted: Sun Sep 16, 2007 2:42 am    Post subject: Reply with quote

You can ask any question you have about linux or UNIX/BSD
and i could more than likely give you an answer or point you in the right direction but as far as windows ummm your on your own :)
Back to top
gallen
Familiar Face


Joined: 01 Sep 2007
Posts: 10

PostPosted: Sun Sep 16, 2007 4:00 am    Post subject: Reply with quote

Oh sorry, I just looked through the example, I'm pretty comfortable with g_signal_connect on standard signals and events.

My problem is really creating my own signals and emitting them. I've been trying to read the api on g_signal_new() and g_signal_emit() but it seems very complicated and I can't get their examples to work in my own code - I keep getting errors that the signal is invalid for the instance.
I am pushed for time which is why I can't spend too long figuring out the entire workings of the gobject system, I just thought that my problem is possibly very easy to solve without needing to have a complete understanding.

If this is not the case, than just let me know, because I have thought of a work around, it just means modifying a lot of my existing code which will be a pain! :) .

My code is:
Code: (Plaintext)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

in main function:
media_signal = g_signal_newv("media-signal", G_TYPE_OBJECT,
                        G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE |
                        G_SIGNAL_NO_HOOKS,
                        NULL, NULL, NULL,
                        g_cclosure_marshal_VOID__VOID,
                        G_TYPE_NONE, 0, NULL);

then later:
g_signal_connect(G_OBJECT(home), "media-signal",
            G_CALLBACK(home_media_signal_cb), NULL);
(amongst other connections, but I'm only doing 1 atm to try to get it to work)

and later....
 g_signal_emit(home, media_signal, 0, NULL);


home is a HildonWindow (an extension of GtkWindow), the error occurs when the g_signal_connect() function is called. Also the only reason why i put home as the first argument of g_signal_emit() is because I thought I had to??


Thanks very much for your help anyway, its reassuring to know that there are people out there who unconditionally give up their time for others.
Back to top
caracal
GTK+ Geek


Joined: 21 Jun 2007
Posts: 91
Location: Wilkes Barre Pa

PostPosted: Mon Sep 17, 2007 1:48 pm    Post subject: Reply with quote

Quote:
i've been trying to read the api on g_signal_new() and g_signal_emit() but it seems very complicated and I can't get their examples to work in my own code


The gtk+ api is simple once you understand the fundamentals for instance

GtkWidget *window;

Code: (Plaintext)
1
GtkWidget*          gtk_window_new                      (GtkWindowType type);


(GtkWindowType type)
1. GTK_WINDOW_TOPLEVEL)
2. GTK_WINDOW_POPUP)

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

Code: (Plaintext)
1
void                gtk_window_set_title                (GtkWindow *window,  const gchar *title);


gtk_window_set_title (GTK_WINDOW (window), "Caracal FileManager v0.0.1");

Quote:
I am pushed for time which is why I can't spend too long figuring out the entire workings of the gobject system, I just thought that my problem is possibly very easy to solve without needing to have a complete understanding.


This is how bugs are created. if you don't full understand how gobject works then your not ready
to progress onto anything other than the basic workings.

As far as the code you posted all i can tell you is to go to the link below and read they entire
tutorial a couple of times.

See here:
http://le-hacker.org/papers/gobject/index.html

And then google for "g_signal_newv" and read some example code.[/code][/quote]

Well i was going to show you how to compile your gtk application for optimization but once again phpBB refuses to let me post certain types of formated text. <-- To the moderators.
Back to top
gallen
Familiar Face


Joined: 01 Sep 2007
Posts: 10

PostPosted: Tue Sep 18, 2007 2:21 am    Post subject: Reply with quote

No worries, thanks.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    GTK+ Forums Forum Index -> GTK+ Programming 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