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

📄 sec-eventhandling.html

📁 gtk 开发手册和参考文档。 包括gtk glib gdk等
💻 HTML
字号:
<HTML><HEAD><TITLE>Event Handling</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.49"><LINKREL="HOME"TITLE="GTK+ 1.2 Tutorial"HREF="gtk-tut.html"><LINKREL="UP"TITLE="Scribble, A Simple Example Drawing Program"HREF="ch-scribble.html"><LINKREL="PREVIOUS"TITLE="Scribble, A Simple Example Drawing Program"HREF="ch-scribble.html"><LINKREL="NEXT"TITLE="The DrawingArea Widget, And Drawing"HREF="sec-thedrawingareawidget.html"></HEAD></head><body bgcolor="#FFFFFF" marginheight=0 marginwidth=0 width="100%"><table cellspacing=6 border=0 cellpadding=0 width="100%">  <tr>    <td bgcolor="#FFFFFF" valign=top nowrap>    <centeR><A HREF="/"><img src="/images/gtk-logo-rgb.gif" width=107 height=140 border=0></A>      <font face="helvetica,lucidia" color="#000000"><BR><BR><b>GTK+<BR>The GIMP Toolkit</b></center><BR><table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B>General</B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="/">Introduction</A><BR><A HREF="/screenshots/">Screenshots</A><br><A HREF="/download/">Download</A><br><A HREF="/mailinglists.html">Mailing Lists</A><BR><A HREF="/bindings.html">Language Bindings</A><BR><A HREF="http://gtk.themes.org/">Themes</A><BR><A HREF="/bugs.html">Bug Tracker</A><BR></td></tr></table></td></tr></table><BR>  <table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B>Documentation</B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="/faq/">FAQ</A><br><A HREF="/tutorial/">Tutorial</A><BR><A HREF="/api/">API Reference</A><br><A HREF="/books.html">Published Books</A><BR></td></tr></table></td></tr></table><BR>  <table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B>Projects</B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="http://www.pango.org/">Pango</A><BR><A HREF="http://sources.redhat.com/inti/">Inti</A><BR><A HREF="http://www.gnome.org/">GNOME</A><BR><A HREF="http://user.sgic.fi/~tml/gimp/win32/">GTK+ for Win32</A><br><A HREF="http://people.redhat.com/sopwith/gtkfb/">GtkFB (Framebuffer)</A><br><A HREF="http://www.directfb.org/gtk.xml">GTK+ on DirectFB</A><BR><A HREF="/beos/">GTK+ for BeOS</A></td></tr></table></td></tr></table><BR>  <table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B><B>Applications</B></B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="http://www.gimp.org/">GIMP</A><BR><A HREF="http://www.abiword.org/">Abiword</A><BR><A HREF="http://www.lysator.liu.se/~alla/dia/dia.html">Dia</A><BR><A HREF="http://glade.pn.org/">Glade</A><BR><A HREF="http://www.gnucash.org/">GnuCash</A><BR><A HREF="http://www.gnome.org/projects/gnumeric/">Gnumeric</A><BR><BR><A HREF="http://www.gnome.org/applist/">GNOME Software Map</A><br></td></tr></table></td></tr></table><BR>      </td>  <td bgcolor="#ffffff" valign=top width="99%"><font face="lucida,helvetica"><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GTK+ 1.2 Tutorial</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="ch-scribble.html">&#60;&#60;&#60; Previous</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 25. Scribble, A Simple Example Drawing Program</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="sec-thedrawingareawidget.html">Next &#62;&#62;&#62;</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="SEC-EVENTHANDLING">25.2. Event Handling</A></H1><P>The GTK signals we have already discussed are for high-level actions,such as a menu item being selected. However, sometimes it is useful tolearn about lower-level occurrences, such as the mouse being moved, ora key being pressed. There are also GTK signals corresponding to theselow-level <ICLASS="EMPHASIS">events</I>. The handlers for these signals have anextra parameter which is a pointer to a structure containinginformation about the event. For instance, motion event handlers arepassed a pointer to a GdkEventMotion structure which looks (in part)like:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">struct _GdkEventMotion{  GdkEventType type;  GdkWindow *window;  guint32 time;  gdouble x;  gdouble y;  ...  guint state;  ...};</PRE></TD></TR></TABLE><P><TTCLASS="LITERAL">type</TT> will be set to the event type, in this case<TTCLASS="LITERAL">GDK_MOTION_NOTIFY</TT>, window is the window in which the eventoccurred. <TTCLASS="LITERAL">x</TT> and <TTCLASS="LITERAL">y</TT> give the coordinates of the event.<TTCLASS="LITERAL">state</TT> specifies the modifier state when the eventoccurred (that is, it specifies which modifier keys and mouse buttonswere pressed). It is the bitwise OR of some of the following:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GDK_SHIFT_MASK  GDK_LOCK_MASK   GDK_CONTROL_MASKGDK_MOD1_MASK   GDK_MOD2_MASK   GDK_MOD3_MASK   GDK_MOD4_MASK   GDK_MOD5_MASK   GDK_BUTTON1_MASKGDK_BUTTON2_MASKGDK_BUTTON3_MASKGDK_BUTTON4_MASKGDK_BUTTON5_MASK</PRE></TD></TR></TABLE><P>As for other signals, to determine what happens when an event occurswe call <TTCLASS="LITERAL">gtk_signal_connect()</TT>. But we also need let GTKknow which events we want to be notified about. To do this, we callthe function:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">void gtk_widget_set_events (GtkWidget *widget,                            gint      events);</PRE></TD></TR></TABLE><P>The second field specifies the events we are interested in. Itis the bitwise OR of constants that specify different typesof events. For future reference the event types are:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GDK_EXPOSURE_MASKGDK_POINTER_MOTION_MASKGDK_POINTER_MOTION_HINT_MASKGDK_BUTTON_MOTION_MASK     GDK_BUTTON1_MOTION_MASK    GDK_BUTTON2_MOTION_MASK    GDK_BUTTON3_MOTION_MASK    GDK_BUTTON_PRESS_MASK      GDK_BUTTON_RELEASE_MASK    GDK_KEY_PRESS_MASK         GDK_KEY_RELEASE_MASK       GDK_ENTER_NOTIFY_MASK      GDK_LEAVE_NOTIFY_MASK      GDK_FOCUS_CHANGE_MASK      GDK_STRUCTURE_MASK         GDK_PROPERTY_CHANGE_MASK   GDK_PROXIMITY_IN_MASK      GDK_PROXIMITY_OUT_MASK     </PRE></TD></TR></TABLE><P>There are a few subtle points that have to be observed when calling<TTCLASS="LITERAL">gtk_widget_set_events()</TT>. First, it must be called before the X windowfor a GTK widget is created. In practical terms, this means youshould call it immediately after creating the widget. Second, thewidget must have an associated X window. For efficiency, many widgettypes do not have their own window, but draw in their parent's window.These widgets are:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GtkAlignmentGtkArrowGtkBinGtkBoxGtkImageGtkItemGtkLabelGtkPixmapGtkScrolledWindowGtkSeparatorGtkTableGtkAspectFrameGtkFrameGtkVBoxGtkHBoxGtkVSeparatorGtkHSeparator</PRE></TD></TR></TABLE><P>To capture events for these widgets, you need to use an EventBoxwidget. See the section on the <AHREF="ch-containerwidgets.html#SEC-EVENTBOX">EventBox</A> widget for details.</P><P>For our drawing program, we want to know when the mouse button ispressed and when the mouse is moved, so we specify<TTCLASS="LITERAL">GDK_POINTER_MOTION_MASK</TT> and <TTCLASS="LITERAL">GDK_BUTTON_PRESS_MASK</TT>. We alsowant to know when we need to redraw our window, so we specify<TTCLASS="LITERAL">GDK_EXPOSURE_MASK</TT>. Although we want to be notified via aConfigure event when our window size changes, we don't have to specifythe corresponding <TTCLASS="LITERAL">GDK_STRUCTURE_MASK</TT> flag, because it isautomatically specified for all windows.</P><P>It turns out, however, that there is a problem with just specifying<TTCLASS="LITERAL">GDK_POINTER_MOTION_MASK</TT>. This will cause the server to add a newmotion event to the event queue every time the user moves the mouse.Imagine that it takes us 0.1 seconds to handle a motion event, but theX server queues a new motion event every 0.05 seconds. We will soonget way behind the users drawing. If the user draws for 5 seconds,it will take us another 5 seconds to catch up after they release the mouse button! What we would like is to only get one motionevent for each event we process. The way to do this is to specify <TTCLASS="LITERAL">GDK_POINTER_MOTION_HINT_MASK</TT>. </P><P>When we specify <TTCLASS="LITERAL">GDK_POINTER_MOTION_HINT_MASK</TT>, the server sendsus a motion event the first time the pointer moves after enteringour window, or after a button press or release event. Subsequent motion events will be suppressed until we explicitly ask forthe position of the pointer using the function:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">GdkWindow*    gdk_window_get_pointer     (GdkWindow       *window,					  gint            *x,					  gint            *y,					  GdkModifierType *mask);</PRE></TD></TR></TABLE><P>(There is another function, <TTCLASS="LITERAL">gtk_widget_get_pointer()</TT> whichhas a simpler interface, but turns out not to be very useful, sinceit only retrieves the position of the mouse, not whether the buttonsare pressed.)</P><P>The code to set the events for our window then looks like:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",		      (GtkSignalFunc) expose_event, NULL);  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",		      (GtkSignalFunc) configure_event, NULL);  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",		      (GtkSignalFunc) motion_notify_event, NULL);  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",		      (GtkSignalFunc) button_press_event, NULL);  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK			 | GDK_LEAVE_NOTIFY_MASK			 | GDK_BUTTON_PRESS_MASK			 | GDK_POINTER_MOTION_MASK			 | GDK_POINTER_MOTION_HINT_MASK);</PRE></TD></TR></TABLE><P>We'll save the "expose_event" and "configure_event" handlers forlater. The "motion_notify_event" and "button_press_event" handlersare pretty simple:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">static gintbutton_press_event (GtkWidget *widget, GdkEventButton *event){  if (event-&#62;button == 1 &#38;&#38; pixmap != NULL)      draw_brush (widget, event-&#62;x, event-&#62;y);  return TRUE;}static gintmotion_notify_event (GtkWidget *widget, GdkEventMotion *event){  int x, y;  GdkModifierType state;  if (event-&#62;is_hint)    gdk_window_get_pointer (event-&#62;window, &#38;x, &#38;y, &#38;state);  else    {      x = event-&#62;x;      y = event-&#62;y;      state = event-&#62;state;    }      if (state &#38; GDK_BUTTON1_MASK &#38;&#38; pixmap != NULL)    draw_brush (widget, x, y);    return TRUE;}</PRE></TD></TR></TABLE></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><AHREF="ch-scribble.html">&#60;&#60;&#60; Previous</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="gtk-tut.html">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="sec-thedrawingareawidget.html">Next &#62;&#62;&#62;</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Scribble, A Simple Example Drawing Program</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="ch-scribble.html">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">The DrawingArea Widget, And Drawing</TD></TR></TABLE></DIV>        </td>    </tr></table>  </td>  </tr></table></body></BODY></HTML>

⌨️ 快捷键说明

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