GTK透過GDK來處理事件,GDK會將每個接受到的XEvent轉換為GdkEvent,然後傳播給GtkWidget,引發一個與事件相對應的事件Signal,再透過Callback函式處理事件。 GdkEvent 是個C union的定義:
union GdkEvent
{ GdkEventType type; GdkEventAny any; GdkEventExpose expose; GdkEventNoExpose no_expose; GdkEventVisibility visibility; GdkEventMotion motion; GdkEventButton button; GdkEventScroll scroll; GdkEventKey key; GdkEventCrossing crossing; GdkEventFocus focus_change; GdkEventConfigure configure; GdkEventProperty property; GdkEventSelection selection; GdkEventOwnerChange owner_change; GdkEventProximity proximity; GdkEventClient client; GdkEventDND dnd; GdkEventWindowState window_state; GdkEventSetting setting; GdkEventGrabBroken grab_broken; }; GdkEvent代表所有的事件型態,其成員 GdkEventType 為enum型態,可透過它來了解目前的事件是哪個類型:
GdkEventType type = event->type; // event 的宣告為
GdkEvent *event switch(type) { case GDK_DELETE: g_print("GDK_DELETE"); ... break; case GDK_DESTROY: g_print("GDK_DELETE"); ... break; ... } 一個使用的例子是,您可以設計一個接受所有事件的處理函式,根據GdkEventType來決定對所有事件作過濾處理,方 式就如上面的程式碼片段所示範的,一個GdkEvent可能對應多個GdkEventType,例如GdkButtonEvent可以對應的 GdkEventType有 GDK_BUTTON_PRESS 、 GDK_2BUTTON_PRESS 、 GDK_3BUTTON_PRESS 與GDK_BUTTON_RELEASE 。 每個事件結構有其個別成員,例如GdkEventButton有x與y成員,代表滑鼠游標相對於視窗的位置:
typedef struct {
GdkEventType type; GdkWindow *window; gint8 send_event; guint32 time; gdouble x; gdouble y; gdouble *axes; guint state; guint button; GdkDevice *device; gdouble x_root, y_root; } GdkEventButton; 您可以這麼存取x或y成員:
gdouble x = event->button.x;
gdouble y = event->button.y; 或是將之轉型為GdkEventButton再進行存取:
gdouble x = ((GdkEventButton*)event)->x; gdouble y = ((GdkEventButton*)event)->y; GdkEvent傳播給GtkWidget,引發一個與事件相 對應的事件Signal,您可以使用g_signal_connect()函式連結該Signal與Callback函式來處理事件,事件類型與對應的事 件Signal名稱,基本上就是去掉GDK_名稱,轉為小寫並加上_event名稱,例如:
如果是"event",則代表所有的事件。多個事件類型可能會對應同一個事件Signal,GDK_BUTTON、 GDK_2BUTTON、 GDK_3BUTTON,在事件的Signal連結時,都是使用button_press_event,在Callback函式中,再根據GdkEventType加以處理, 部份的事件則有特殊的方式處理,例如滑鼠拖曳事件。 您也可以參考 GDK Event Types ,以及 Events 中之說明。 |
Impr
|
GTK Gossip: GDK 事件結構
最新推荐文章于 2023-04-14 16:32:06 发布