⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtk-faq.sgml

📁 linux下电话本所依赖的一些图形库
💻 SGML
📖 第 1 页 / 共 5 页
字号:
  signal(SIGCHLD, sigchld_handler);    /* main loop */  gtk_main ();  exit(0);         }</programlisting></sect1><!-- ----------------------------------------------------------------- --><sect1><title>Why don't the contents of a button move when the buttonis pressed? Here's a patch to make it work that way... <emphasis>[GTK 2.x]</emphasis></title><para>From: Peter Mattis</para><para><quote>The reason buttons don't move their child down and tothe right when they are depressed is because I don't thinkthat's what is happening visually. My view of buttons isthat you are looking at them straight on. That is, the userinterface lies in a plane and you're above it lookingstraight at it. When a button gets pressed it moves directlyaway from you. To be absolutely correct I guess the childshould actually shrink a tiny amount. But I don't see whythe child should shift down and to the left. Remember, thechild is supposed to be attached to the buttons surface. Itsnot good for it to appear like the child is slipping on thesurface of the button.</quote></para><para><quote>On a more practical note, I did implement this at one pointand determined it didn't look good and removed it.</quote></para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>How do I identifiy a widgets top level window or otherancestor? <emphasis>[GTK 2.x]</emphasis></title><para>There are a couple of ways to find the top level parentof a widget. The easiest way is to call the<literal>gtk_widget_get_toplevel()</literal> function thatreturns a pointer to a GtkWidget that is the top levelwindow.</para><para>A more complicated way to do this (but less limited, asit allows the user to get the closest ancestor of a known type) is to use<literal>gtk_widget_get_ancestor()</literal> as in:</para><programlisting role="C">      GtkWidget       *widget;      widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);</programlisting><para>Since virtually all the GTK_TYPEs can be used as thesecond parameter of this function, you can get any parentwidget of a particular widget. Suppose you have an hbox whichcontains a vbox, which in turn contains some other atomicwidget (entry, label, etc. To find the master hbox using the<literal>entry</literal> widget simply use:</para><programlisting role="C">      GtkWidget       *hbox;      hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);</programlisting><para>You can also follow the a widgets ancestry by using the function<literal>gtk_widget_get_parent()</literal> that returns a pointerto a widgets parent widget.</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>How do I get the Window ID of a GtkWindow? <emphasis>[GTK 2.x]</emphasis></title><para>The actual Gdk/X window will be created when the widgetgets realized. You can get the Window ID with:</para><programlisting role="C">#include &lt;gdk/gdkx.h&gt;Window xwin = GDK_WINDOW_XWINDOW (GTK_WIDGET (my_window)->window);</programlisting></sect1><!-- ----------------------------------------------------------------- --><sect1><title>How do I catch a double click event? <emphasis>[GTK 2.x]</emphasis></title><para>Tim Janik wrote to gtk-list (slightly modified):</para><para>Define a signal handler:</para><programlisting role="C">gintsignal_handler_event(GtkWidget *widget, GdkEventButton *event, gpointer func_data){  if (GTK_IS_BUTTON(widget) &&       (event->type==GDK_2BUTTON_PRESS ||        event->type==GDK_3BUTTON_PRESS) ) {    printf("I feel %s clicked with button %d\n",           event->type==GDK_2BUTTON_PRESS ? "double" : "triple",           event->button);  }  return FALSE;}</programlisting><para>And connect the handler to your object:</para><programlisting role="C">{  /* button init stuff */       g_signal_connect(G_OBJECT(button),                     "button_press_event",                     G_CALLBACK(signal_handler_event),                     NULL);  /* and/or */  g_signal_connect(G_OBJECT(button),                     "button_release_event",                     G_CALLBACK(signal_handler_event),                     NULL);  /* something else */}</programlisting><para>and, Owen Taylor wrote:</para><para><quote>Note that a single button press will be receivedbeforehand, and if you are doing this for a button, you willtherefore also get a "clicked" signal for the button. (Thisis going to be true for any toolkit, since computers aren'tgood at reading one's mind.)</quote></para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>By the way, what are the differences between signalsand events?</title><para>First of all, Havoc Pennington gives a rather completedescription of the differences between events and signals inhis free book (two chapters can be found at <ulinkurl="http://www106.pair.com/rhp/sample_chapters.html">http://www106.pair.com/rhp/sample_chapters.html</ulink>).</para><para>Moreover, Havoc posted this to the <literal>gtk-list</literal><quote>Events are a stream of messages received from the Xserver. They drive the Gtk main loop; which more or lessamounts to "wait for events, process them" (not exactly, itis really more general than that and can wait on manydifferent input streams at once). Events are a Gdk/Xlibconcept.</quote></para><para><quote>Signals are a feature of GtkObject and its subclasses. Theyhave nothing to do with any input stream; really a signal is just a wayto keep a list of callbacks around and invoke them ("emit" thesignal). There are lots of details and extra features ofcourse. Signals are emitted by object instances, and are entirelyunrelated to the Gtk main loop.  Conventionally, signals are emitted"when something changes" about the object emitting thesignal.</quote></para><para><quote>Signals and events only come together because GtkWidgethappens to emit signals when it gets events. This is purely aconvenience, so you can connect callbacks to be invoked when aparticular widget receives a particular event. There is nothing aboutthis that makes signals and events inherently related concepts, any morethan emitting a signal when you click a button makes button clicking andsignals related concepts.</quote></para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>Data I pass to the <literal>delete_event</literal> (or other event)handler gets corrupted.</title><para>All event handlers take an additional argument whichcontains information about the event that triggered thehandler. So, a <literal>delete_event</literal> handler mustbe declared as:</para><programlisting role="C">gint delete_event_handler (GtkWidget   *widget,                           GdkEventAny *event,                           gpointer     data);</programlisting></sect1><!-- ----------------------------------------------------------------- --><sect1><title>I have my signal connected to the the (whatever) event,but it seems I don't catch it. What's wrong?</title><para>There is some special initialisation to do in order tocatch some particular events. In fact, you must set thecorrect event mask bit of your widget before getting someparticular events.</para><para>For example,</para><programlisting role="C">  gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);</programlisting><para>lets you catch the key release events. If you want tocatch every events, simply us the GDK_ALL_EVENTS_MASK eventmask.</para><para>All the event masks are defined in the<filename>gdktypes.h</filename> file.</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>I need to add a new signal to a GTK+ widget. Anyidea?</title><para>If the signal you want to add may be beneficial forother GTK+ users, you may want to submit a patch thatpresents your changes. Check the tutorial for moreinformation about adding signals to a widget class.</para><para>If you don't think it is the case or if your patch isnot applied you'll have to use the<literal>gtk_object_class_user_signal_new</literal>function. <literal>gtk_object_class_user_signal_new</literal> allows youto add a new signal to a predefined GTK+ widget without anymodification of the GTK+ source code. The new signal can beemited with <literal>gtk_signal_emit</literal> and can behandled in the same way as other signals.</para><para>Tim Janik posted this code snippet:</para><programlisting role="C">static guint signal_user_action = 0;signal_user_action =  gtk_object_class_user_signal_new (gtk_type_class (GTK_TYPE_WIDGET),                    "user_action",                    GTK_RUN_LAST | GTK_RUN_ACTION,                    gtk_marshal_NONE__POINTER,                    GTK_TYPE_NONE, 1,                    GTK_TYPE_POINTER);voidgtk_widget_user_action (GtkWidget *widget,                        gpointer   act_data){  g_return_if_fail (GTK_IS_WIDGET (widget));  gtk_signal_emit (GTK_OBJECT (widget), signal_user_action, act_data);}</programlisting><para>If you want your new signal to have more than theclassical gpointer parameter, you'll have to play with GTK+marshallers.</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>Is it possible to get some text displayed which istruncated to fit inside its allocation?</title><para>GTK's behavior (no clipping) is a consequence of itsattempts to conserve X resources. Label widgets (amongothers) don't get their own X window - they just draw theircontents on their parent's window. While it might be possibleto have clipping occur by setting the clip mask beforedrawing the text, this would probably cause a substantialperformance penalty.</para><para>Its possible that, in the long term, the best solutionto such problems might be just to change gtk to give labels Xwindows. A short term workaround is to put the label widgetinside another widget that does get its own window - onepossible candidate would be the viewport widget.</para><programlisting role="C">viewport = gtk_viewport (NULL, NULL);gtk_widget_set_usize (viewport, 50, 25);gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_NONE);gtk_widget_show(viewport);label = gtk_label ("a really long label that won't fit");gtk_container_add (GTK_CONTAINER(viewport), label);gtk_widget_show (label);</programlisting><para>If you were doing this for a bunch of widgets, you mightwant to copy gtkviewport.c and strip out the adjustment andshadow functionality (perhaps you could call itGtkClipper).</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>How do I make my window modal? / How do I make a singlewindow active?</title><para>After you create your window, do<literal>gtk_grab_add(my_window)</literal>. And after closing the windowdo <literal>gtk_grab_remove(my_window)</literal>.</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>Why doesn't my widget (e.g. progressbar)update? <emphasis>[GTK 2.x]</emphasis></title><para>You are probably doing all the changes within a function withoutreturning control to <literal>gtk_main()</literal>. This maybe the case if you do some lengthy calculation in yourcode. Most drawing updates are only placed on a queue, whichis processed within <literal>gtk_main()</literal>. You can force thedrawing queue to be processed using something like:</para><programlisting role="C">while (g_main_context_iteration(NULL, FALSE));</programlisting><para>inside you're function that changes the widget.</para><para>What the above snippet does is run all pending eventsand high priority idle functions, then return immediately(the drawing is done in a high priority idle function).</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>How do I attach data to some GTK+ object/widget?<emphasis>[GTK 2.x]</emphasis></title><para>First of all, the attached data is stored in theobject_data field of a GtkObject. The type of this field isGData, which is defined in glib.h.  So you should read thegdataset.c file in your glib source directory verycarefully.</para><para>There are two (easy) ways to attach some data to a gtkobject.  Using <literal>g_object_set_data()</literal> and<literal>g_object_get_data()</literal> seems to be the mostcommon way to do this, as it provides a powerful interface toconnect objects and data.</para><programlisting role="C">void g_object_set_data(GObject *object, const gchar *key, gpointer data);gpointer g_object_get_data(GObject *object, const gchar *key);</programlisting><para>Since a short example is better than any lengthy speech:</para><programlisting role="C">struct my_struct	p1,p2,*result;GtkWidget		*w;g_object_set_data(G_OBJECT(w),"p1 data",(gpointer)&amp;p1);g_object_set_data(G_OBJECT(w),"p2 data",(gpointer)&amp;p2);result = g_object_get_data(G_OBJECT(w),"p1 data");</programlisting><para>The <literal>gtk_object_set_user_data()</literal> and<literal>gtk_object_get_user_data()</literal> functions doesexactly the same thing as the functions above, but does notlet you specify the "key" parameter.Instead, it uses astandard "user_data" key. Note that the use of these functionsis deprecated in 1.2. They only provide a compatibility modewith some old gtk packages.</para></sect1><!-- ----------------------------------------------------------------- --><sect1><title>How do I remove the data I have attached to anobject?</title><para>When attaching the data to the object, you can use the<literal>gtk_object_set_data_full()</literal> function. The threefirst arguments of the function are the same as in<literal>gtk_object_set_data()</literal>. The fourth

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -