GtkDrawingArea에서 key-press-event 시그널 받기

Posted by 미스란디르 Sun, 10 Feb 2008 18:33:00 GMT

GtkDrawingArea + Cairo를 이용해서 간단한 걸 만들고 있다.

그림판이랑 비슷한 부분이 아주 조금 있는데, 예를들면 어떤 그림 조각을 움직인다던가, 혹은 선택하고 복사해서 옆에 새걸 만든다던가 하는것.

C-c 로 복사하고 C-p 로 붙여넣고, DEL로 지우고 따위의 행동을 하려면 key-press-event를 사용하는게 좋겠다고 생각하고, gsignalconnect 로 연결해봤다.

그런데 시그널이 전혀 안들어온다. 참고로 button-press-event 라거나 motion-notify-event같은건 잘 받아진다.

그래서 구글에게 신탁을 해 보았는데, GtkDrawingArea 문서를 알려준다.

To receive mouse events on a drawing area, you will need to enable them with gtk_widget_add_events(). To receive keyboard events, you will need to set the GTK_CAN_FOCUS flag on the drawing area, and should probably draw some user-visible indication that the drawing area is focused. Use the GTK_HAS_FOCUS() macro in your expose event handler to decide whether to draw the focus indicator. See gtk_paint_focus() for one way to draw focus.

마우스 이벤트를 받으려면 gtk_widget_add_events() 를 해야하고, 키보드 이벤트를 받으려면 GTK_CAN_FOCUS flag를 세팅해야 한단다. GTK_HAS_FOCUS() 가지고 검사해서 뭔가 표시하라는건 덤이다.

그래서 다음과 같이 했다.

cpp:

widget = glade_xml_get_widget (xml, "drawing_area");
GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_FOCUS);
g_signal_connect (widget, "button-press-event", on_button_press_event, NULL);
g_signal_connect (widget, "key-press-event", on_key_press_event, NULL);
.
.
.
gboolean on_button_press_event (GtkWidget *w, GtkEventButton *e, gpointer userdata)
{
  gtk_widget_grab_focus (w);
  return TRUE;
}

gboolean on_button_press_event (GtkWidget *w, GtkEventKey *e, gpointer userdata)
{
  g_printf("%d:%d\n", e->state, e->keyval);
  return TRUE;
}

focus를 가질 수 있게 하고, 버튼을 누르면 focus를 가져오게 한다. 그리고 key-press-event를 연결하면 끝. 아 사실 gtk_widget_add_events()로 이벤트 마스크도 더해줘야 하는데, 요건 글레이드 에디터에서 해버렸다.

아무튼 저걸로 잘 된다.

Posted in  | Tags ,  | no comments | no trackbacks