?? z109.html
字號:
</div> <p> <b>Figure 4. Using Signals</b> </p> </div> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="SEC-EMITTING">Emitting A Signal</a> </h2> <p> It's your object's responsibility to emit its signals at appropriate times. This is very simple; if you've saved the return value from <tt class="FUNCTION"> gtk_signal_new()</tt>, that identifier can be used to emit the signal. Otherwise, you can emit the signal by name (with some cost in execution speed, since GTK+ will have to look up the identifier in a hash table). </p> <p> Here is code from <tt class="FILENAME"> gtk/gtkbutton.c</tt> which is used to emit the <span class="SYMBOL">"button_pressed"</span> signal: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgtk_button_pressed (GtkButton *button){ g_return_if_fail (button != NULL); g_return_if_fail (GTK_IS_BUTTON (button)); gtk_signal_emit (GTK_OBJECT (button), button_signals[PRESSED]);} </pre> </td> </tr> </table> <p> If a signal has arguments (other than the standard two), you must specify those as a variable argument list: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], &widget->requisition); </pre> </td> </tr> </table> <p> If a signal returns a value, you must pass a location for the returned value as the final argument: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gint return_val; return_val = FALSE; gtk_signal_emit (GTK_OBJECT (widget), widget_signals[EVENT], event, &return_val); </pre> </td> </tr> </table> <p> Notice that <span class="STRUCTNAME">return_val</span> is initialized to something sane; if there are no signal handlers, none of them will assign a value to <span class="STRUCTNAME">return_val</span>. So you must initialize the variable. Each signal handler's return value will be assigned to the same location, so the final value of <span class="STRUCTNAME">return_val</span> is determined by the last signal handler to run. Note that certain return values (such as strings) must be freed by the signal emitter. </p> <p> <tt class="FUNCTION">gtk_signal_emit_by_name()</tt> is the same as <tt class="FUNCTION">gtk_signal_emit()</tt>, except that the second argument is a signal name rather than a signal ID number. There are also variants of both emission functions that take a vector of <span class= "STRUCTNAME">GtkArg</span> instead of a variable argument list. These variants expect arrays of <i class= "EMPHASIS">n+1</i><span class="STRUCTNAME">GtkArg</span> structs, where <i class="EMPHASIS">n</i> is the number of signal arguments and there is an additional <span class= "STRUCTNAME">GtkArg</span> for the return value. The <span class="STRUCTNAME">GtkArg</span> structs should be initialized with sane values. If the function returns no value, the return value <span class="STRUCTNAME"> GtkArg</span> will have <span class="STRUCTNAME"> GTK_TYPE_NONE</span>. </p> <p> All four signal emission functions are summarized in <a href="z109.html#FL-SIGNALEMISSION">Figure 5</a>. </p> <div class="FIGURE"> <a name="FL-SIGNALEMISSION"></a> <div class="FUNCSYNOPSIS"> <a name="FL-SIGNALEMISSION.SYNOPSIS"></a> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="FUNCSYNOPSISINFO">#include <gtk/gtksignal.h></pre> </td> </tr> </table> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION">gtk_signal_emit</tt></code>(GtkObject* <tt class="PARAMETER"><i>object</i></tt>, guint <tt class="PARAMETER"><i>signal_id</i></tt>, <tt class= "PARAMETER"><i>...</i></tt>);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION"> gtk_signal_emit_by_name</tt></code>(GtkObject* <tt class="PARAMETER"><i>object</i></tt>, const gchar* <tt class="PARAMETER"><i>name</i></tt>, <tt class= "PARAMETER"><i>...</i></tt>);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION">gtk_signal_emitv</tt></code>(GtkObject* <tt class="PARAMETER"><i>object</i></tt>, guint <tt class="PARAMETER"><i>signal_id</i></tt>, GtkArg* <tt class="PARAMETER"><i>params</i></tt>);</code> </p> <p> <code><code class="FUNCDEF">void <tt class= "FUNCTION"> gtk_signal_emitv_by_name</tt></code>(GtkObject* <tt class="PARAMETER"><i>object</i></tt>, const gchar* <tt class="PARAMETER"><i>name</i></tt>, GtkArg* <tt class="PARAMETER"><i>params</i></tt>);</code> </p> </div> <p> <b>Figure 5. Signal Emission</b> </p> </div> <p> Keep in mind that it is usually inappropriate to simply emit a signal outside of an object's implementation. Only <span class="STRUCTNAME">GTK_RUN_ACTION</span> signals are guaranteed to work properly without special setup or shutdown. Objects often export functions you can use to emit signals properly; for example, to emit the <span class="SYMBOL">"size_request"</span> signal, <tt class= "CLASSNAME">GtkWidget</tt> provides this function: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> voidgtk_widget_size_request (GtkWidget *widget, GtkRequisition *requisition){ g_return_if_fail (widget != NULL); g_return_if_fail (GTK_IS_WIDGET (widget)); gtk_widget_ref (widget); gtk_widget_ensure_style (widget); gtk_signal_emit (GTK_OBJECT (widget), widget_signals[SIZE_REQUEST], &widget->requisition); if (requisition) gtk_widget_get_child_requisition (widget, requisition); gtk_widget_unref (widget);} </pre> </td> </tr> </table> <p> As you can see, particular actions are required before and after emitting the signal; thus it should only be emitted via the <tt class="FUNCTION"> gtk_widget_size_request()</tt> function. </p> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="SEC-EMISSION">What Happens When A Signal Is Emitted</a> </h2> <p> Given the many different options when creating signals and connecting callbacks, you may be thoroughly confused about what happens when a signal is emitted. Here's a summary of the sequence of events: </p> <ol type="1"> <li> <p> If you are emitting the signal by name, the signal ID is looked up. </p> </li> <li> <p> If another emission of the same signal is in progress, and the signal has the <span class= "STRUCTNAME">GTK_RUN_NO_RECURSE</span> flag set, GTK+ signals the previous emission to restart and this emission ends. </p> </li> <li> <p> If the signal is <span class="STRUCTNAME"> GTK_RUN_FIRST</span>, the default signal handler is called using the signal's marshaller. If the emission is stopped from within the handler, (using <tt class= "FUNCTION">gtk_emit_stop_by_name()</tt> or one of its cousins), this emission ends. If the signal is re-emitted from within the handler and is <span class="STRUCTNAME">GTK_RUN_NO_RECURSE</span>, this emission restarts. </p> </li> <li> <p> If there are any emission hooks installed for this signal, they are invoked. GTK+ does <i class= "EMPHASIS">not</i> check whether the emission has been stopped or re-emitted at this point; it will not check until the next step. Emission hooks should not re-emit the signal they are watching, or try to stop the emission. </p> </li> <li> <p> Any normally-connected callbacks are invoked using the signal's marshaller. Callbacks connected with <tt class="FUNCTION">gtk_signal_connect_after()</tt> are not invoked at this point. After invoking each callback, GTK+ checks whether it stopped the signal and the emission ends if so. GTK+ also checks whether the signal was re-emitted, and if so restarts the emission process for <span class="STRUCTNAME"> GTK_RUN_NO_RECURSE</span> signals. </p> </li> <li> <p> If the signal is <span class="STRUCTNAME"> GTK_RUN_LAST</span>, the default handler is invoked. Afterward GTK+ again checks whether the emission has been stopped or should be restarted. </p> </li> <li> <p> Any callbacks connected with <tt class="FUNCTION"> gtk_signal_connect_after()</tt> are invoked. After invoking each one, GTK+ checks whether the emission should be stopped or restarted. </p> </li> </ol> <p> Within each step the handlers are invoked in the order they were connected. The order of the steps is fixed: <span class="STRUCTNAME">GTK_RUN_FIRST</span> default handler, emission hooks, normal connections, <span class= "STRUCTNAME">GTK_RUN_LAST</span> default handler, "after" connections. </p> </div> </div> <div class="NAVFOOTER"> <br> <br> <table width="100%" border="0" bgcolor="#ffffff" cellpadding= "1" cellspacing="0"> <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> <tr> <td colspan="2" align="left"> <font color="#000000" size="2"><b>Object Arguments</b></font> </td> <td colspan="2" align="right"> <font color="#000000" size="2"><b>Object Finalization</b></font> </td> </tr> </table> </div> </body></html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -