?? z109.html
字號:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html> <head> <title> Signals </title> <meta name="GENERATOR" content= "Modular DocBook HTML Stylesheet Version 1.45"> <link rel="HOME" title="GTK+ / Gnome Application Development" href="ggad.html"> <link rel="UP" title="The GTK+ Object and Type System" href= "cha-objects.html"> <link rel="PREVIOUS" title="Object Arguments" href= "hc-objectargs.html"> <link rel="NEXT" title="Object Finalization" href= "sec-finalization.html"> </head> <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink= "#840084" alink="#0000FF"> <div class="NAVHEADER"> <table width="100%" border="0" bgcolor="#ffffff" cellpadding= "1" cellspacing="0"> <tr> <th colspan="4" align="center"> <font color="#000000" size="2">GTK+ / Gnome Application Development</font> </th> </tr> <tr> <td width="25%" bgcolor="#ffffff" align="left"> <a href="hc-objectargs.html"><font color="#0000ff" size="2"><b><<< Previous</b></font></a> </td> <td width="25%" colspan="2" bgcolor="#ffffff" align= "center"> <font color="#0000ff" size="2"><b><a href="ggad.html"> <font color="#0000ff" size="2"><b> Home</b></font></a></b></font> </td> <td width="25%" bgcolor="#ffffff" align="right"> <a href="sec-finalization.html"><font color="#0000ff" size="2"><b>Next >>></b></font></a> </td> </tr> </table> </div> <div class="SECT1"> <h1 class="SECT1"> <a name="Z109">Signals</a> </h1> <p> A <span class="STRUCTNAME">GtkObject</span> can emit a <i class="FIRSTTERM">signal</i>. Signals are stored in a global table by GTK+. <i class="FIRSTTERM">Handlers</i> or <i class="FIRSTTERM">callbacks</i> can be <i class= "FIRSTTERM">connected</i> to signals; when a signal is <i class="FIRSTTERM">emitted</i>, its callbacks are invoked. The process of invoking all handlers for a signal is called <i class="FIRSTTERM">emission</i>. </p> <p> Abstractly, a signal is a <i class="EMPHASIS">kind</i> of message that an object wants to broadcast; the kind of message is associated with certain conditions (such as the user selecting a list item) and with message-specific parameter types which are passed to connected callbacks (such as the index of the row the user selected). User callbacks are connected to a particular signal and to a particular object instance. That is, you do not connect callbacks to the <span class="SYMBOL">"clicked"</span> signal of all buttons; rather, you connect to the <span class="SYMBOL">"clicked"</span> signal of a particular one. (However, there is a way to monitor all emissions of a signal---these callbacks are called "emission hooks.") </p> <p> Signals are typically associated with a class function pointer which is invoked every time the signal is emitted; if non-<span class="STRUCTNAME">NULL</span>, the pointed-to class function serves as a default handler for the signal. It is up to the author of each <span class="STRUCTNAME"> GtkObject</span> subclass whether to provide a space in the class struct for a default handler, and whether to implement the default handler in the base class. Conventionally, signals have the same name as the class function they are associated with. </p> <p> For example, the <span class="STRUCTNAME"> GtkButtonClass</span> struct has a member called <span class="STRUCTNAME">clicked</span>; this member is registered as the default handler for the <span class= "SYMBOL">"clicked"</span> signal. However, the <tt class= "CLASSNAME">GtkButton</tt> base class does not implement a default handler, and leaves the <span class="STRUCTNAME"> clicked</span> member set to <span class="STRUCTNAME"> NULL</span>. Subclasses of <tt class="CLASSNAME"> GtkButton</tt> could optionally fill it in with an appropriate function. If <tt class="CLASSNAME"> GtkButton</tt> did implement a default <span class= "STRUCTNAME">clicked</span> handler, subclasses could still override it with a different one. </p> <p> Note that GTK+ signals have nothing to do with UNIX signals. Sometimes new GTK+ users confuse the two. </p> <div class="SECT2"> <h2 class="SECT2"> <a name="SEC-ADDINGSIGNAL">Adding a New Signal</a> </h2> <p> Once you understand the GTK+ type system and <span class= "STRUCTNAME">GtkArg</span>, signal registration is fairly transparent. Here is the signal registration code from <tt class="CLASSNAME">GtkButton</tt> again: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> button_signals[PRESSED] = gtk_signal_new ("pressed", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkButtonClass, pressed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); button_signals[RELEASED] = gtk_signal_new ("released", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkButtonClass, released), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); button_signals[CLICKED] = gtk_signal_new ("clicked", GTK_RUN_FIRST | GTK_RUN_ACTION, object_class->type, GTK_SIGNAL_OFFSET (GtkButtonClass, clicked), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); button_signals[ENTER] = gtk_signal_new ("enter", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkButtonClass, enter), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); button_signals[LEAVE] = gtk_signal_new ("leave", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkButtonClass, leave), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); gtk_object_class_add_signals (object_class, button_signals, LAST_SIGNAL); </pre> </td> </tr> </table> <p> Earlier in <tt class="FILENAME">gtkbutton.c</tt>, an enumeration and an array were declared as follows: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> enum { PRESSED, RELEASED, CLICKED, ENTER, LEAVE, LAST_SIGNAL};static guint button_signals[LAST_SIGNAL] = { 0 }; </pre> </td> </tr> </table> <p> <tt class="FUNCTION">gtk_signal_new()</tt> has the following effects: </p> <ul> <li> <p> It registers the name of the signal. </p> </li> <li> <p> It associates the signal with a particular <span class="STRUCTNAME">GtkType</span>. </p> </li> <li> <p> It tells GTK+ where to find the default handler in the class struct, if any. </p> </li> <li> <p> It tells GTK+ what signature the signal's callbacks will have. </p> </li> <li> <p> It registers a <i class="FIRSTTERM">marshaller</i>, a function which invokes the signal's callbacks in an appropriate way. </p> </li> <li> <p> It generates an integer identifier which can be used to refer to the signal. (If you refer to the symbol by name, GTK+ will find the ID associated with the name and then use the ID.) </p> </li> </ul> <p> <tt class="FUNCTION">gtk_object_class_add_signals()</tt> attaches signal identifiers to the object's class struct, so the signals for a given class can be rapidly located. Conventionally, the argument to this function is an enumeration-indexed static array, as shown for <tt class= "CLASSNAME">GtkButton</tt>. The static array is also useful when implementing the functionality of the class (the signal identifiers are used to emit the signals). </p> <p> The first argument to <tt class="FUNCTION"> gtk_signal_new()</tt> is a name for the signal; you refer to the signal by name when you call <tt class="FUNCTION"> gtk_signal_connect()</tt>, for example. The third argument is the <span class="STRUCTNAME">GtkType</span> of the object type emitting the signal, and the fourth is the location of the associated class function in the type's class struct. A macro is provided to compute the offset. If you specify an offset of <span class= "STRUCTNAME">0</span>, no class function will be associated with the signal. Note that giving a zero offset is distinct from giving a valid offset but setting the function member in the struct to <span class= "STRUCTNAME">NULL</span>; in the latter case, subclasses of the object can fill in a value for the default handler. </p> <p> The second argument is a bitfield. Here are the associated flags: </p> <ul> <li> <p> <span class="STRUCTNAME">GTK_RUN_FIRST</span> means that the default handler in the class struct, if any, will run before user-connected callbacks. If this flag is set, signal handlers should not return a value. </p> </li> <li> <p> <span class="STRUCTNAME">GTK_RUN_LAST</span> means the opposite, the default handler will run last. (Caveat: user callbacks connected with <tt class= "FUNCTION">gtk_signal_connect_after()</tt> run after a <span class="STRUCTNAME">GTK_RUN_LAST</span> default handler. There is no way to ensure a default handler is <i class="EMPHASIS">always</i> run last. <span class="STRUCTNAME">GTK_RUN_FIRST</span> handlers are always first, however.) </p> </li> <li> <p> <span class="STRUCTNAME">GTK_RUN_BOTH</span> is an alias for <span class="STRUCTNAME">(GTK_RUN_FIRST | GTK_RUN_LAST)</span>, so the default handler will run twice (on either side of user-connected callbacks). </p> </li> <li> <p> <span class="STRUCTNAME">GTK_RUN_NO_RECURSE</span> means that the signal should not be called recursively. If a handler for a signal emits the same signal again, normally the second emission is performed as usual (calling all handlers), and then the first emission continues, invoking its remaining handlers. With <span class="STRUCTNAME"> GTK_RUN_NO_RECURSE</span> in effect, a second emission aborts the first emission (ignoring any handlers that remain), and restarts the emission process. So only one emission is in progress at a time. (Right now this is used only for <span class= "STRUCTNAME">GtkAdjustment</span>'s <span class= "SYMBOL">"changed"</span> and <span class="SYMBOL"> "value_changed"</span> signals. Usually you don't care about how many times a value changed, only whether it changed and its most recent value. <span class="STRUCTNAME">GTK_RUN_NO_RECURSE</span> "compresses" multiple emissions into a single emission.) </p> </li> <li> <p> <span class="STRUCTNAME">GTK_RUN_ACTION</span> means the signal can be "bound" and invoked by the user. In other words, no special setup or shutdown is required in order to emit it. Among other things, GTK+ will
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -