Each object is encapsulated in Gtk programming. And it is not recommended to use global variables because they are prone to make the program complicated. So, we need something to communicate between objects. There are two ways to do so.
tb = gtk_text_view_get_buffer (tv)
is an instance
method on the instance tv
. The caller requests
tv
to give tb
, which is a GtkTextBuffer
instance connected to tv
.activate
signal on GApplication
object. When the application is activated, the signal is emitted. Then
the handler, which has been connected to the signal, is invoked.The caller of methods or signals are usually out of the object. One of the difference between these two is that the object is active or passive. In methods, objects passively respond to the caller. In signals, objects actively send signals to handlers.
GObject signals are registered, connected and emitted.
g_signal_connect
family
functions. A default handler is always called on any instance of the
class.g_signal_connect
or its family functions. The connection is
usually done out of the object. One important thing is that signals are
connected on a certain instance. Suppose there exist two GtkButton
instances A, B and a function C. Even if you connected the “clicked”
signal on A to C, B and C are not connected.In TfeTextView, two signals are registered.
tv->file
is changed.tfe_text_view_open
doesn’t return the status because it can’t get the status from the file
chooser dialog. (Instead, the call back function gets the status.) This
signal is emitted instead of the return value of the function.A static variable or array is used to store signal ID.
enum {
,
CHANGE_FILE,
OPEN_RESPONSE
NUMBER_OF_SIGNALS};
static guint tfe_text_view_signals[NUMBER_OF_SIGNALS];
Signals are registered in the class initialization function.
static void
tfe_text_view_class_init (TfeTextViewClass *class) {
GObjectClass *object_class = G_OBJECT_CLASS (class);
object_class->dispose = tfe_text_view_dispose;
tfe_text_view_signals[CHANGE_FILE] = g_signal_new ("change-file",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
0 /* class offset */,
NULL /* accumulator */,
NULL /* accumulator data */,
NULL /* C marshaller */,
G_TYPE_NONE /* return_type */,
0 /* n_params */
);
tfe_text_view_signals[OPEN_RESPONSE] = g_signal_new ("open-response",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST | G_SIGNAL_NO_RECURSE | G_SIGNAL_NO_HOOKS,
0 /* class offset */,
NULL /* accumulator */,
NULL /* accumulator data */,
NULL /* C marshaller */,
G_TYPE_NONE /* return_type */,
1 /* n_params */,
G_TYPE_INT
);
}
g_signal_new
function is used. The signal “change-file” has no default handler
(object method handler) so the offset (the line 9) is set to zero. You
usually don’t need a default handler. If you need it, use
g_signal_new_class_handler
function instead of
g_signal_new
. See GObject
API Reference for further information.g_signal_new
is the signal id. The
type of signal id is guint, which is the same as unsigned int. It is
used in the function g_signal_emit
.G_TYPE_INT
is a type of
integer. Such fundamental types are described in GObject
reference manual.The handlers are declared as follows.
/* "change-file" signal handler */
void
(TfeTextView *tv,
user_function )
gpointer user_data
/* "open-response" signal handler */
void
(TfeTextView *tv,
user_function -id,
TfeTextViewOpenResponseType response) gpointer user_data
tv
points the instance on which the signal
is emitted.user_data
comes from the fourth
argument of g_signal_connect
.parameter
(response-id
) comes from the
fourth argument of g_signal_emit
.The values of the type TfeTextViewOpenResponseType
are
defined in tfetextview.h
.
/* "open-response" signal response */
enum TfeTextViewOpenResponseType
{
,
TFE_OPEN_RESPONSE_SUCCESS,
TFE_OPEN_RESPONSE_CANCEL
TFE_OPEN_RESPONSE_ERROR};
TFE_OPEN_RESPONSE_SUCCESS
when
tfe_text_view_open
has successfully opened a file and read
it.TFE_OPEN_RESPONSE_CANCEL
when
the user has canceled.TFE_OPEN_RESPONSE_ERROR
when an
error has occurred.A signal and a handler are connected by the function macro
g_signal_connect
. There are some similar function macros
like g_signal_connect_after
,
g_signal_connect_swapped
and so on. However,
g_signal_connect
is used most often. The signals
“change-file” and “open-response” are connected to their callback
functions out of the TfeTextView object. Those callback functions are
defined by users.
For example, callback functions are defined in
src/tfe6/tfewindow.c
and their names are
file_changed_cb
and open_response_cb
. They
will be explained later.
(GTK_TEXT_VIEW (tv), "change-file", G_CALLBACK (file_changed_cb), nb);
g_signal_connect
(TFE_TEXT_VIEW (tv), "open-response", G_CALLBACK (open_response_cb), nb); g_signal_connect
A signal is emitted on the instance. A function
g_signal_emit
is used to emit the signal. The following
lines are extracted from src/tfetextview/tfetextview.c
.
Each line comes from a different line.
(tv, tfe_text_view_signals[CHANGE_FILE], 0);
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_SUCCESS);
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_CANCEL);
g_signal_emit (tv, tfe_text_view_signals[OPEN_RESPONSE], 0, TFE_OPEN_RESPONSE_ERROR); g_signal_emit