?? hc-objectargs.html
字號(hào):
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><html> <head> <title> Object Arguments </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="GtkArg and the Type System" href= "sec-gtkarg.html"> <link rel="NEXT" title="Signals" href="z109.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="sec-gtkarg.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="z109.html"><font color="#0000ff" size="2"><b> Next >>></b></font></a> </td> </tr> </table> </div> <div class="SECT1"> <h1 class="SECT1"> <a name="HC-OBJECTARGS">Object Arguments</a> </h1> <p> <i class="FIRSTTERM">Arguments</i> are one of the most interesting features of <span class="STRUCTNAME"> GtkObject</span>. Arguments are a mechanism for handling what CORBA's Interface Definition Language (IDL) calls an <i class="FIRSTTERM">attribute</i>: a value with a "getter" and a "setter." In concrete terms, object arguments pair a key (which is a string) with a value (represented as a <span class="STRUCTNAME">GtkArg</span>). Each <span class= "STRUCTNAME">GtkObject</span> subclass can register permissible keys and the <span class="STRUCTNAME"> GtkType</span>s of their associated values. </p> <p> Using object arguments, one can discover at runtime what attributes an object has, and then get or set their values. This is very useful for people implementing GUI builders, since some of the widget configuration dialogs can be automated. Similarly, it makes it much easier to write GTK+ bindings for scripting languages. It can also be convenient for programmers, since they can avoid writing all the get/set functions---the <tt class="CLASSNAME"> GnomeCanvas</tt>, for example, uses object arguments for almost all of its API. Finally, object arguments may be configurable via the <tt class="FILENAME">gtkrc</tt> configuration mechanism in a future version of GTK+, making it possible for users to extensively customize GTK+ software. </p> <div class="SECT2"> <h2 class="SECT2"> <a name="Z106">Setting Object Arguments</a> </h2> <p> Most commonly, arguments are used as an API to set attributes of widgets. However, not all of the GTK+ API has been exported via arguments, so it is not always possible. </p> <p> To set widget attributes, the most convenient interface is <tt class="FUNCTION">gtk_object_set()</tt>. Here's an example: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_object_set(GTK_OBJECT(vbox), "GtkContainer::border_width", (gulong) 10, NULL); </pre> </td> </tr> </table> <p> The above code is identical in effect to: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_container_set_border_width(GTK_CONTAINER(vbox), 10); </pre> </td> </tr> </table> <p> It's up to you which to use; it depends on the context. Typically, you would use the argument mechanism if you have a reason to, i.e. if you are using its dynamic, runtime-oriented features. However, if you are setting several attributes, it may be easier to type and read. </p> <p> <tt class="FUNCTION">gtk_object_set()</tt> takes a <span class="STRUCTNAME">GtkObject</span> as the first argument, followed by any number of key-value pairs. If a key is not defined for the object you pass in, a runtime error will be triggered. The list of key-value pairs must be terminated with a <span class="STRUCTNAME">NULL</span> key. When a <span class="STRUCTNAME">GtkObject</span> registers itself with GTK+, it tells GTK+ what type of value to expect after each key. For the aggregate fundamental types <tt class="FUNCTION"> gtk_object_set()</tt> will expect more than one C function argument after the key. For example, first a signal function and then a user data pointer will be expected after <span class="STRUCTNAME"> GTK_TYPE_SIGNAL</span> arguments. (<a href= "sec-gtkarg.html#TABLE-FUNDTYPES">Table 1 in the section called <i><span class="STRUCTNAME">GtkArg</span> and the Type System</i></a> gives the types of the expected arguments.) </p> <p> It is permissible to leave off the object class portion of an argument name---<span class= "STRUCTNAME">"GtkContainer::border_width"</span> can be simply <span class="STRUCTNAME">"border_width"</span>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_object_set(GTK_OBJECT(vbox), "border_width", (gulong) 10, NULL); </pre> </td> </tr> </table> <p> If you do not specify the class name as part of the argument name, GTK+ will start with the real type of the object and look up the argument name in the argument table for each superclass until it finds the right one (<tt class="CLASSNAME">GtkContainer</tt> in this case). If you do specify the class name, GTK+ will only look for the argument in the specified class's argument table. </p> <p> Since <tt class="FUNCTION">gtk_object_set()</tt> uses C variable argument lists, it has limited type safety. This can be a real problem in your code. You may have noticed the cast to <span class="STRUCTNAME">gulong</span> in the sample call to <tt class="FUNCTION"> gtk_object_set()</tt>. The argument <span class= "STRUCTNAME">GtkContainer::border_width</span> has type <span class="STRUCTNAME">GTK_TYPE_ULONG</span>. GTK+ will extract <span class="STRUCTNAME">sizeof(gulong)</span> bytes from the argument list when it encounters this argument. If you leave out the cast, C will probably pass only <span class="STRUCTNAME">sizeof(gint)</span> bytes to the function. As you might imagine, this causes memory corruption on many platforms. A similar problem arises with arguments of type <span class="STRUCTNAME"> GTK_TYPE_DOUBLE</span>; if you type <span class= "STRUCTNAME">5</span> instead of <span class= "STRUCTNAME">5.0</span>, C will pass an integer to <tt class="FUNCTION">gtk_object_set()</tt>. These bugs are very hard to find, once you introduce them. </p> <p> <tt class="FUNCTION">gtk_object_set()</tt> is syntactic sugar for a more fundamental function call, <tt class= "FUNCTION">gtk_object_setv()</tt>. <tt class="FUNCTION"> gtk_object_setv()</tt> takes a vector of <span class= "STRUCTNAME">GtkArg</span> (<tt class= "FUNCTION">gtk_object_set()</tt> converts each key-value pair in its argument list to <span class="STRUCTNAME"> GtkArg</span> internally). </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> GtkArg args[1]; args[0].name = "GtkContainer::border_width"; args[0].type = GTK_TYPE_ULONG; GTK_VALUE_ULONG(args[0]) = 10; gtk_object_setv(GTK_OBJECT(button), 1, args); </pre> </td> </tr> </table> <p> The second argument to <tt class="FUNCTION"> gtk_object_setv()</tt> is the length of the array of <span class="STRUCTNAME">GtkArg</span>. <tt class= "FUNCTION">gtk_object_set()</tt> is plainly easier to use when you are typing the code in manually, but <tt class= "FUNCTION">gtk_object_setv()</tt> can be passed a dynamically-constructed argument array---which is convenient if you're exporting GTK+ functionality to an interpreted environment. </p> <p> It is also possible to set object arguments when objects are created. You can create most objects using the <tt class="FUNCTION">gtk_object_new()</tt> function, and most widgets with the <tt class="FUNCTION"> gtk_widget_new()</tt> function. The routines take a <span class="STRUCTNAME">GtkType</span> as their first argument, and create an object or widget of that type. They then take a list of argument-value pairs, just as <tt class="FUNCTION">gtk_object_set()</tt> does. There are also <tt class="FUNCTION">gtk_object_newv()</tt> and <tt class="FUNCTION">gtk_widget_newv()</tt> variants. </p> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="Z107">Reading Object Arguments</a> </h2> <p> To get the value of one or more arguments, you simply create an array of <span class="STRUCTNAME"> GtkArg</span>, filling in the <span class="STRUCTNAME"> name</span> field of each <span class="STRUCTNAME"> GtkArg</span>. <tt class="FUNCTION"> gtk_object_getv()</tt> fills in the <span class= "STRUCTNAME">type</span> fields and the argument values. If an error occurs, the <span class="STRUCTNAME"> type</span> field is set to <span class="STRUCTNAME"> GTK_TYPE_INVALID</span>. If the fundamental type of the returned value is <span class="STRUCTNAME"> GTK_TYPE_STRING</span>, <span class="STRUCTNAME"> GTK_TYPE_BOXED</span>, or <span class="STRUCTNAME"> GTK_TYPE_ARGS</span>, you are responsible for freeing it. </p> <p> Here's a simple example: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> GtkArg args[2]; args[0].name = "GtkContainer::border_width"; args[1].name = "GtkContainer::resize_mode"; gtk_object_getv(GTK_OBJECT(button), 2, args); g_assert(args[0].type == GTK_TYPE_ULONG); g_assert(args[1].type == GTK_TYPE_RESIZE_MODE); g_assert(GTK_FUNDAMENTAL_TYPE(args[1].type) == GTK_TYPE_ENUM); printf("Border width: %lu Resize mode: %d\n", GTK_VALUE_ULONG(args[0]), GTK_VALUE_ENUM(args[1])); </pre> </td> </tr> </table> </div> <div class="SECT2"> <h2 class="SECT2"> <a name="SEC-GETSETARG">Using Object Arguments in Your Own <span class="STRUCTNAME">GtkObject</span> Subclass</a> </h2> <p> If you're writing a custom <span class="STRUCTNAME"> GtkObject</span> or a custom subclass of some existing object, you can register your own object arguments in the class initialization function, at the same time you register your object's signals. To do this, call <tt class="FUNCTION">gtk_object_add_arg_type()</tt>---here's an example from <tt class="CLASSNAME">GtkContainer</tt>: </p> <table border="0" bgcolor="#E0E0E0" width="100%"> <tr> <td><pre class="PROGRAMLISTING"> gtk_object_add_arg_type("GtkContainer::border_width", GTK_TYPE_ULONG, GTK_ARG_READWRITE, ARG_BORDER_WIDTH); </pre> </td> </tr> </table> <p> The first argument must be a static string constant, because GTK+ does not copy it. It must also begin with the name of your new class, separated from the name of the argument by two colons (reminiscent of the C++ scope operator). The second argument should be the type of the argument; this can be any <span class="STRUCTNAME"> GtkType</span> GTK+ knows about. </p> <p> The third argument contains one or more flags, defined in <tt class="FILENAME">gtk/gtkobject.h</tt>. The available flags are: </p> <ul> <li> <p> <span class="STRUCTNAME">GTK_ARG_READABLE</span> means the argument's value can be read, using <tt class="FUNCTION">gtk_object_getv()</tt>. </p> </li> <li> <p> <span class="STRUCTNAME">GTK_ARG_WRITABLE</span> means the argument's value can be written, using <tt class="FUNCTION">gtk_object_set()</tt> or <tt class= "FUNCTION">gtk_object_setv()</tt> </p> </li> <li> <p> <span class="STRUCTNAME">GTK_ARG_CONSTRUCT</span> means the argument should be initialized with a default value. This applies to numeric and pointer types; they are set to <span class="STRUCTNAME"> 0</span> or <span class="STRUCTNAME">NULL</span>, respectively. (This happens within <tt class= "FUNCTION">gtk_object_new()</tt> or <tt class= "FUNCTION">gtk_widget_new()</tt>, which call <tt class="FUNCTION"> gtk_object_default_construct()</tt>.) </p> </li> <li> <p> <span class="STRUCTNAME"> GTK_ARG_CONSTRUCT_ONLY</span> means the argument is <i class="EMPHASIS">only</i> used for object construction; it cannot be read or written later. That is, you can't use these arguments with <tt class="FUNCTION">gtk_object_set()</tt>. </p> </li> <li> <p> <span class="STRUCTNAME">GTK_ARG_CHILD_ARG</span> is used by subclasses of <tt class="CLASSNAME"> GtkContainer</tt>; <tt class="CLASSNAME"> GtkContainer</tt> implements a specialized variation on the argument system to permit setting the attributes of child-container pairs (such as packing flags for <tt class="CLASSNAME">GtkBox</tt>---the flags are not a property of the child or the container, but of the pair). You will only use this flag if you're writing a new type of container, or some other kind of object with similar semantics. </p> </li> <li> <p> <span class="STRUCTNAME">GTK_ARG_READWRITE</span> is
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -