GTK Gossip: GDK 事件結構

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名稱,例如:
GDK_DELETE delete_event
GDK_DESTROY destroy_event
GDK_EXPOSE expose_event
GDK_MOTION_NOTIFY motion_notify_event
GDK_BUTTON_PRESS button_press_event
GDK_2BUTTON_PRESS button_press_event
GDK_3BUTTON_PRESS button_press_event
GDK_BUTTON_RELEASE button_release_event
GDK_KEY_PRESS key_press_event
GDK_KEY_RELEASE key_release_event
GDK_ENTER_NOTIFY enter_notify_event
GDK_LEAVE_NOTIFY leave_notify_event
GDK_FOCUS_CHANGE focus_in_event, focus_out_event
GDK_CONFIGURE configure_event
GDK_MAP map_event
GDK_UNMAP unmap_event
GDK_PROPERTY_NOTIFY property_notify_event
GDK_SELECTION_CLEAR selection_clear_event
GDK_SELECTION_REQUEST selection_request_event
GDK_SELECTION_NOTIFY selection_notify_event
GDK_PROXIMITY_IN proximity_in_event
GDK_PROXIMITY_OUT proximity_out_event
GDK_CLIENT_EVENT client_event
GDK_VISIBILITY_NOTIFY visibility_notify_event
GDK_WINDOW_STATE window_state_event
GDK_NO_EXPOSE no_expose_event

如果是"event",則代表所有的事件。多個事件類型可能會對應同一個事件Signal,GDK_BUTTON、 GDK_2BUTTON、 GDK_3BUTTON,在事件的Signal連結時,都是使用button_press_event,在Callback函式中,再根據GdkEventType加以處理, 部份的事件則有特殊的方式處理,例如滑鼠拖曳事件。

您也可以參考 GDK Event Types ,以及 Events 中之說明。


 

 

冬天臉會乾,又怕擦乳液油膩膩?
專屬男人的俐落保養,露得清男性「雙效控油保濕乳」控油、保濕一次搞定!馬上挑戰就可抽全系列商品!
更多訊息..
寶寶眼睛如此脆弱容易受刺激!
不讓寶寶紅眼睛,你選對沐浴產品了嗎?快來了解選擇嬰兒產品的真相!
更多訊息..

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值