?? z109.html
字號:
allow users to bind keyboard accelerators to these signals using statements in the <tt class="FILENAME"> .gtkrc</tt> configuration file. </p> </li> <li> <p> <span class="STRUCTNAME">GTK_RUN_NO_HOOKS</span> means that emission hooks are not allowed (you can't monitor this signal for an entire object type, only for particular object instances). It is used for <span class="STRUCTNAME">GtkObject</span>'s <span class="SYMBOL">"destroy"</span> signal because hooks are not invoked on objects with the <span class= "STRUCTNAME">GTK_DESTROYED</span> flag set and that flag is set before emitting <span class="SYMBOL"> "destroy"</span>. It's probably not good for anything else. </p> </li> </ul> <p> The last few arguments to <tt class="FUNCTION"> gtk_signal_new()</tt> provide a <i class="FIRSTTERM"> marshaller</i>, and tell GTK+ the marshaller's type. A marshaller invokes a callback function, based on an array of <span class="STRUCTNAME">GtkArg</span> it receives from GTK+. Marshallers are needed because C function argument lists cannot be constructed at runtime. GTK+ comes with a number of prewritten marshallers; here is the one used for all <tt class="CLASSNAME">GtkButton</tt> signals: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef void (*GtkSignal_NONE__NONE) (GtkObject* object, gpointer user_data);void gtk_marshal_NONE__NONE (GtkObject * object, GtkSignalFunc func, gpointer func_data, GtkArg * args){ GtkSignal_NONE__NONE rfunc; rfunc = (GtkSignal_NONE__NONE) func; (*rfunc) (object, func_data);} </pre> </td> </tr> </table> <p> As you can see, the <span class="STRUCTNAME"> NONE__NONE</span> refers to the fact that the expected callback type returns no value and has no "special" arguments. GTK+ automatically passes the object emitting the signal and a <span class="STRUCTNAME"> user_data</span> field to all callbacks; special signal arguments are inserted in between these two. Since there are no signal-specific arguments in this case, the array of <span class="STRUCTNAME">GtkArg</span> is ignored. </p> <p> The naming convention for marshallers places a double underscore between the return value and the special arguments, if any. Here's a more complex example: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef gint (*GtkSignal_INT__POINTER) (GtkObject * object, gpointer arg1, gpointer user_data);void gtk_marshal_INT__POINTER (GtkObject * object, GtkSignalFunc func, gpointer func_data, GtkArg * args){ GtkSignal_INT__POINTER rfunc; gint *return_val; return_val = GTK_RETLOC_INT (args[1]); rfunc = (GtkSignal_INT__POINTER) func; *return_val = (*rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);} </pre> </td> </tr> </table> <p> Notice that the last element of the array of <span class= "STRUCTNAME">GtkArg</span> is a space for the return value; if there is no return value, this element will have type <span class="STRUCTNAME">GTK_TYPE_NONE</span> and can be ignored. GTK+ provides macros such as <tt class="FUNCTION">GTK_RETLOC_INT()</tt> to extract a "return location" from a <span class="STRUCTNAME"> GtkArg</span>. Similar <span class="STRUCTNAME"> GTK_RETLOC_</span> macros exist for all the fundamental types. </p> <p> The function pointer signatures in the class structure for an object will correspond to the type of the signal. This is a convenient way to find out what signature the callbacks connected to a signal should have, if the GTK+ header files are readily available on your system. </p> <p> The last arguments to <tt class="FUNCTION"> gtk_signal_new()</tt> give the type of the signal's marshaller. First a return value type is given, then the number of special arguments, then a variable argument list containing that many <span class="STRUCTNAME"> GtkType</span> values in the appropriate order. Since <tt class="CLASSNAME">GtkButton</tt> has no examples of signals with arguments, here is one from <tt class= "CLASSNAME">GtkWidget</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> widget_signals[BUTTON_PRESS_EVENT] = gtk_signal_new("button_press_event", GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (GtkWidgetClass, button_press_event), gtk_marshal_BOOL__POINTER, GTK_TYPE_BOOL, 1, GTK_TYPE_GDK_EVENT); </pre> </td> </tr> </table> <p> <span class="SYMBOL">"button_press_event"</span> returns a boolean value, and has a <span class="STRUCTNAME"> GdkEvent*</span> argument. Notice that the marshaller works with any <span class="STRUCTNAME"> GTK_TYPE_POINTER</span>, but the signal requires the more-specific boxed type <span class="STRUCTNAME"> GTK_TYPE_GDK_EVENT</span>, allowing language bindings to query the correct <i class="EMPHASIS">kind</i> of pointer. </p> <p> Signals can have many arguments; here is one from <tt class="CLASSNAME">GtkCList</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> clist_signals[SELECT_ROW] = gtk_signal_new ("select_row", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GtkCListClass, select_row), gtk_marshal_NONE__INT_INT_POINTER, GTK_TYPE_NONE, 3, GTK_TYPE_INT, GTK_TYPE_INT, GTK_TYPE_GDK_EVENT); </pre> </td> </tr> </table> <p> The <span class="SYMBOL">"select_row"</span> signal returns no value, but has three arguments (the selected row and column number, and the event that caused the selection). </p> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z110">Using Existing Signals</a> </h2> <p> <a href="z109.html#FL-USINGSIGNALS">Figure 4</a> shows the wide array of functions available for manipulating signals. You should already be familiar with the most fundamental signal operation: connecting a signal handler to be invoked when the signal is emitted, like this: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(delete_event_cb), NULL); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(button_click_cb), label); </pre> </td> </tr> </table> <p> You may not be aware that <tt class="FUNCTION"> gtk_signal_connect()</tt> returns a "handler ID" which can be used to refer to the connection it creates. Using the handler ID, you can unregister the callback with <tt class="FUNCTION">gtk_signal_disconnect()</tt>. You can also temporarily "block" the callback by calling <tt class="FUNCTION">gtk_signal_handler_block()</tt>. This increments a "block count"; the callback will not be invoked until the block count returns to <tt class= "APPLICATION">0</tt>. <tt class="FUNCTION"> gtk_signal_handler_unblock()</tt> decrements the block count. Both <tt class="FUNCTION"> gtk_signal_disconnect()</tt> and <tt class="FUNCTION"> gtk_signal_handler_unblock()</tt> have variants that search for the handler ID given a callback function or user data pointer; these are possibly more convenient, with some loss of efficiency. </p> <p> It can be useful to block signal handlers if you'll be changing some aspect of an object yourself, and thus don't need to run the callbacks you use to respond to user actions. For example, you normally change some boolean variable if the user clicks a toggle button, in a callback to the <span class="SYMBOL">"toggled"</span> signal. If you update the toggle button programmatically because the flag was changed via some mechanism other than the button, <span class="SYMBOL">"toggled"</span> will still be emitted; but you want to block your callback, since the flag is already correct. </p> <p> <tt class="FUNCTION">gtk_signal_connect()</tt> is not the only way to connect to a signal. You can also use <tt class="FUNCTION">gtk_signal_connect_object()</tt>; this simply swaps the signal-emitting object pointer and the user data pointer in the arguments passed to the callback. Normally, the object comes first, then any arguments unique to the signal, and finally the user data pointer; with <tt class="FUNCTION"> gtk_signal_connect_object()</tt>, the object is last and user data is first. This function is useful when you want to use a pre-existing function as a callback without writing a wrapper to move its arguments. For example: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_signal_connect_object(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), GTK_OBJECT(dialog)); </pre> </td> </tr> </table> <p> Because the user data and the button are swapped, the first argument to <tt class="FUNCTION"> gtk_widget_destroy()</tt> will be the dialog rather than the button, closing the dialog. When using <tt class= "FUNCTION">gtk_signal_connect_object()</tt>, your callback data must be a <span class="STRUCTNAME"> GtkObject</span> to avoid confusing marshallers that expect an object as their first argument. </p> <p> <tt class="FUNCTION">gtk_signal_connect_after()</tt> asks GTK+ to run the callback after the object's default signal handler, rather than before it. This only works with certain signals, those with the <span class= "STRUCTNAME">GTK_RUN_LAST</span> flag set; <a href= "z109.html#SEC-ADDINGSIGNAL">the section called <i>Adding a New Signal</i></a> explains this flag. </p> <p> <tt class="FUNCTION"> gtk_signal_connect_object_after()</tt> combines the effects of <tt class="FUNCTION"> gtk_signal_connect_object()</tt> and <tt class= "FUNCTION">gtk_signal_connect_after()</tt>. </p> <p> <tt class="FUNCTION">gtk_signal_connect_full()</tt> gives you complete control over the connection and is mostly useful in language bindings. The <span class= "STRUCTNAME">object_signal</span> and <span class= "STRUCTNAME">after</span> arguments can be <span class= "STRUCTNAME">TRUE</span> or <span class="STRUCTNAME"> FALSE</span>, toggling argument order and time of callback invocation. The functions we just mentioned also let you change this, so <tt class="FUNCTION"> gtk_signal_connect_full()</tt> adds little. Its unique features are the ability to specify a callback marshaller, and the ability to specify a <span class= "STRUCTNAME">GtkDestroyNotify</span> function. Notice that <tt class="FUNCTION">gtk_signal_connect_full()</tt> does not expect the same kind of marshaller described in <a href="z109.html#SEC-ADDINGSIGNAL">the section called <i>Adding a New Signal</i></a>; it expects a more general marshaller appropriate for marshalling functions written in languages other than C. If you give a non-<span class= "STRUCTNAME">NULL</span><span class= "STRUCTNAME">GtkDestroyNotify</span> function, it will be invoked on the user data pointer when this handler is disconnected or the <span class="STRUCTNAME"> GtkObject</span> is destroyed. Here is the proper signature for the function: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> typedef void (*GtkDestroyNotify) (gpointer data);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -