GTK+ Forums

Discussion forum for GTK+ and Programming. Ask questions, troubleshoot problems, view and post example code, or express your opinions.
It is currently Thu Oct 02, 2014 2:31 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Connecting widgets to signals
PostPosted: Sat Sep 15, 2007 7:44 am 
Offline
Familiar Face

Joined: Sat Sep 01, 2007 7:16 am
Posts: 10
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


Top
 Profile  
 
 Post subject:
PostPosted: Sat Sep 15, 2007 8:46 am 
Offline
GTK+ Guru

Joined: Thu Jun 21, 2007 1:52 pm
Posts: 198
Location: Wilkes Barre Pa
scribble-simple.c

Code:

/* 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.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 16, 2007 2:25 am 
Offline
Familiar Face

Joined: Sat Sep 01, 2007 7:16 am
Posts: 10
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.


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 16, 2007 2:42 am 
Offline
GTK+ Guru

Joined: Thu Jun 21, 2007 1:52 pm
Posts: 198
Location: Wilkes Barre Pa
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 :)


Top
 Profile  
 
 Post subject:
PostPosted: Sun Sep 16, 2007 4:00 am 
Offline
Familiar Face

Joined: Sat Sep 01, 2007 7:16 am
Posts: 10
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:
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.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Sep 17, 2007 1:48 pm 
Offline
GTK+ Guru

Joined: Thu Jun 21, 2007 1:52 pm
Posts: 198
Location: Wilkes Barre Pa
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:
GtkWidget*          gtk_window_new                      (GtkWindowType type);


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

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

Code:
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.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Sep 18, 2007 2:21 am 
Offline
Familiar Face

Joined: Sat Sep 01, 2007 7:16 am
Posts: 10
No worries, thanks.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group