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

📄 gtkfaq.txt

📁 gtk是linux一款强大的夸平台的图形化开发工具
💻 TXT
📖 第 1 页 / 共 5 页
字号:
           }  55..44..  WWhhyy ddoonn''tt tthhee ccoonntteennttss ooff aa bbuuttttoonn mmoovvee wwhheenn tthhee bbuuttttoonn iiss  pprreesssseedd?? HHeerree''ss aa ppaattcchh ttoo mmaakkee iitt wwoorrkk tthhaatt wwaayy......  From: Peter Mattis       The reason buttons don't move their child down and to the       right when they are depressed is because I don't think       that's what is happening visually. My view of buttons is       that you are looking at them straight on. That is, the user       interface lies in a plane and you're above it looking       straight at it. When a button gets pressed it moves directly       away from you. To be absolutely correct I guess the child       should actually shrink a tiny amount. But I don't see why       the child should shift down and to the left. Remember, the       child is supposed to be attached to the buttons surface. Its       not good for it to appear like the child is slipping on the       surface of the button.  On a more practical note, I did implement this at one point  and determined it didn't look good and removed it.  55..55..  HHooww ttoo II iiddeennttiiffiiyy aa wwiiddggeettss ttoopp lleevveell wwiinnddooww oorr ootthheerr aanncceessttoorr??  There are a couple of ways to find the top level parent of a widget.  The easier way is to call the gtk_widget_top_level() function that  returns a pointer to a GtkWidget that is the top level window.  A more complicated way to do this (but less limited, as it allows the  user to get the closest ancestor of a known type) is to use  gtk_widget_get_ancestor() as in:             GtkWidget       *widget;             widget = gtk_widget_get_ancestor(w, GTK_TYPE_WINDOW);  Since virtually all the GTK_TYPEs can be used as the second parameter  of this function, you can get any parent widget of a particular  widget. Suppose you have an hbox which contains a vbox, which in turn  contains some other atomic widget (entry, label, etc. To find the  master hbox using the entry widget simply use:             GtkWidget       *hbox;             hbox = gtk_widget_get_ancestor(w, GTK_TYPE_HBOX);  55..66..  HHooww ddoo II ccaattcchh aa ddoouubbllee cclliicckk eevveenntt ((iinn aa lliisstt wwiiddggeett,, ffoorr eexxaamm--  ppllee))??  Tim Janik wrote to gtk-list (slightly modified):  Define a signal handler:       gint       signal_handler_event(GtkWiget *widget, GdkEvenButton *event, gpointer func_data)       {         if (GTK_IS_LIST_ITEM(widget) &&              (event->type==GDK_2BUTTON_PRESS ||               event->type==GDK_3BUTTON_PRESS) ) {           printf("I feel %s clicked on button %d\",                  event->type==GDK_2BUTTON_PRESS ? "double" : "triple",                  event->button);         }         return FALSE;       }  And connect the handler to your object:       {         /* list, list item init stuff */         gtk_signal_connect(GTK_OBJECT(list_item),                            "button_press_event",                            GTK_SIGNAL_FUNC(signal_handler_event),                            NULL);         /* and/or */         gtk_signal_connect(GTK_OBJECT(list_item),                            "button_release_event",                            GTK_SIGNAL_FUNC(signal_handler_event),                            NULL);         /* something else */       }  and, Owen Taylor wrote:  Note that a single button press will be received beforehand, and if  you are doing this for a button, you will therefore also get a  "clicked" signal for the button. (This is going to be true for any  toolkit, since computers aren't good at reading one's mind.)  55..77..  BByy tthhee wwaayy,, wwhhaatt aarree tthhee ddiiffffeerreenncceess bbeettwweeeenn ssiiggnnaallss aanndd eevveennttss??  First of all, Havoc Pennington gives a rather complete description of  the differences between events and signals in his free book (two  chapters can be found at  http://www106.pair.com/rhp/sample_chapters.html).  Moreover, Havoc posted this to the gtk-list       Events are a stream of messages received from the X server.       They drive the Gtk main loop; which more or less amounts to       "wait for events, process them" (not exactly, it is really       more general than that and can wait on many different input       streams at once). Events are a Gdk/Xlib concept.       Signals are a feature of GtkObject and its subclasses. They       have nothing to do with any input stream; really a signal is       just a way to keep a list of callbacks around and invoke       them ("emit" the signal). There are lots of details and       extra features of course. Signals are emitted by object       instances, and are entirely unrelated to the Gtk main loop.       Conventionally, signals are emitted "when something changes"       about the object emitting the signal.       Signals and events only come together because GtkWidget       happens to emit signals when it gets events. This is purely       a convenience, so you can connect callbacks to be invoked       when a particular widget receives a particular event. There       is nothing about this that makes signals and events       inherently related concepts, any more than emitting a signal       when you click a button makes button clicking and signals       related concepts.  55..88..  II hhaavvee mmyy ssiiggnnaall ccoonnnneecctteedd ttoo tthhee tthhee ((wwhhaatteevveerr)) eevveenntt,, bbuutt iitt  sseeeemmss II ddoonn''tt ccaattcchh iitt.. WWhhaatt''ss wwrroonngg??  There is some special initialisation to do in order to catch some  particular events. In fact, you must set the correct event mask bit of  your widget before getting some particular events.  For example,         gtk_widget_add_events(window, GDK_KEY_RELEASE_MASK);  lets you catch the key release events. If you want to catch every  events, simply us the GDK_ALL_EVENTS_MASK event mask.  All the event masks are defined in the gdktypes.h file.  55..99..  IIss iitt ppoossssiibbllee ttoo ggeett ssoommee tteexxtt ddiissppllaayyeedd wwhhiicchh iiss ttrruunnccaatteedd ttoo  ffiitt iinnssiiddee iittss aallllooccaattiioonn??  GTK's behavior (no clipping) is a consequence of its attempts to  conserve X resources. Label widgets (among others) don't get their own  X window - they just draw their contents on their parent's window.  While it might be possible to have clipping occur by setting the clip  mask before drawing the text, this would probably cause a substantial  performance penalty.  Its possible that, in the long term, the best solution to such  problems might be just to change gtk to give labels X windows.  A  short term workaround is to put the label widget inside another widget  that does get it's own window - one possible candidate would be the  viewport widget.       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);  If you were doing this for a bunch of widgets, you might want to copy  gtkviewport.c and strip out the adjustment and shadow functionality  (perhaps you could call it GtkClipper).  55..1100..  HHooww ddoo II mmaakkee mmyy wwiinnddooww mmooddaall?? // HHooww ddoo II mmaakkee aa ssiinnggllee wwiinnddooww  aaccttiivvee??  After you create your window, do gtk_grab_add(my_window). And after  closing the window do gtk_grab_remove(my_window).  55..1111..  WWhhyy ddooeessnn''tt mmyy wwiiddggeett ((ee..gg.. pprrooggrreessssbbaarr)) uuppddaattee??  You are probably doing all the changes within a function without  returning control to gtk_main(). This may be the case if you do some  lengthy calculation in your code. Most drawing updates are only placed  on a queue, which is processed within gtk_main(). You can force the  drawing queue to be processed using something like:       while (gtk_events_pending())               gtk_main_iteration();  inside you're function that changes the widget.  What the above snippet does is run all pending events and high  priority idle functions, then return immediately (the drawing is done  in a high priority idle function).  55..1122..  HHooww ddoo II aattttaacchh ddaattaa ttoo ssoommee GGTTKK++ oobbjjeecctt//wwiiddggeett??  First of all, the attached data is stored in the object_data field of  a GtkObject. The type of this field is GData, which is defined in  glib.h.  So you should read the gdataset.c file in your glib source  directory very carefully.  There are two (easy) ways to attach some data to a gtk object.  Using  gtk_object_set_data() and gtk_object_get_data() seems to be the most  common way to do this, as it provides a powerfull interface to connect  objects and data.       void gtk_object_set_data(GtkObject *object, const gchar *key, gpointer data);       gpointer gtk_object_get_data(GtkObject *object, const gchar *key);  Since a short example is better than any lengthy speech:       struct my_struct        p1,p2,*result;       GtkWidget               *w;       gtk_object_set_data(GTK_OBJECT(w),"p1 data",(gpointer)&p1);       gtk_object_set_data(GTK_OBJECT(w),"p2 data",(gpointer)&p2);       result = gtk_object_get_data(GTK_OBJECT(w),"p1 data");  The gtk_object_set_user_data() and gtk_object_get_user_data()  functions does exactly the same thing as the functions above, but does  not let you specify the "key" parameter.  Instead, it uses a standard  "user_data" key. Note that the use of these functions is deprecated in  1.2. They only provide a compatibility mode with some old gtk  packages.  55..1133..  HHooww ddoo II rreemmoovvee tthhee ddaattaa II hhaavvee aattttaacchheedd ttoo aann oobbjjeecctt??  When attaching the data to the object, you can use the  gtk_object_set_data_full() function. The three first arguments of the  function are the same as in gtk_object_set_data(). The fourth one is a  pointer to a callback function which is called when the data is  destroyed. The data is destroyed when you:  +o  destroy the object  +o  replace the data with a new one (with the same key)  +o  replace the data with NULL (with the same key)  55..1144..  HHooww ccoouulldd II ggeett aannyy wwiiddggeettss ppoossiittiioonn??  As Tim Janik pointed out, there are different cases, and each case  requires a different solution.  +o  If you want the position of a widget relative to its parent, you     should use widget->allocation.x and widget->allocation.y.  +o  If you want the position of a window relative to the X root window,     you should use gdk_window_get_geometry() or     gdk_window_get_origin().  +o  Last but not least, if you want to get a Window Manager frame     position, you should use gdk_window_get_deskrelative_origin().  55..1155..  HHooww ddoo II sseett tthhee ssiizzee ooff aa wwiiddggeett//wwiinnddooww?? HHooww ddoo II pprreevveenntt tthhee  uusseerr rreessiizziinngg mmyy wwiinnddooww??  The gtk_widget_set_uposition() function is used to set the position of  any widget.  The gtk_widget_set_usize() function is used to set the size of a  widget. In order to use all the features that are provided by this  function when it acts on a window, you may want to use the  gtk_window_set_policy function. The definition of these functions is:       void        gtk_widget_set_usize (GtkWidget *widget,                                         gint width,                                         gint height);       void        gtk_window_set_policy (GtkWindow *window,                                          gint allow_shrink,                                          gint allow_grow,                                          gint auto_shrink);  Auto_shrink will automatically shrink the window when the requested  size of the child widgets goes below the current size of the window.  Allow_shrink will give the user the authorisation to make the window  smaller that it should normally be. Allow_grow will give the user will  have the ability to make the window bigger. The default values for  these parameters are:       allow_shrink = FALSE       allow_grow   = TRUE       auto_shrink  = FALSE  55..1166..  HHooww ddoo II aadddd aa ppooppuupp mmeennuu ttoo mmyy GGTTKK++ aapppplliiccaattiioonn??  The menu example in the examples/menu directory of the GTK+  distribution implements a popup menu with this technique :       static gint button_press (GtkWidget *widget, GdkEvent *event)       {           if (event->type == GDK_BUTTON_PRESS) {               GdkEventButton *bevent = (GdkEventButton *) event;               gtk_menu_popup (GTK_MENU(widget), NULL, NULL, NULL, NULL,                               bevent->button, bevent->time);               /* Tell calling code that we have handled this event; the buck                * stops here. */               return TRUE;           }           /* Tell calling code that we have not handled this event; pass it on. */           return FALSE;       }  55..1177..  HHooww ddoo II ddiissaabbllee oorr eennaabbllee aa wwiiddggeett,, ssuucchh aass aa bbuuttttoonn??  To disable (or to enable) a widget, use the gtk_widget_set_sensitive()  function. The first parameter is you widget pointer. The second  parameter is a boolean value: when this value is TRUE, the widget is  enabled.  55..1188..  SShhoouullddnn''tt tthhee tteexxtt aarrgguummeenntt iinn tthhee ggttkk__cclliisstt__** ffuunnccttiioonnss bbee  ddeeccllaarreedd ccoonnsstt??  For example:  gint gtk_clist_prepend (GtkCList    *clist,                          gchar       *text[]);  Answer: No, while a type "gchar*" (pointer to char) can automatically  be cast into "const gchar*" (pointer to const char), this does not

⌨️ 快捷键说明

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