當前嘗試創建基於GtkWidget
的自定義小部件,將其標記爲可繪製並使用cairo繪製內容。對於上下文來說非常重要。事件回調未在自定義gtk3小部件中執行
當我嘗試處理事件(這樣我就可以實現縮放) - 尤其是滾動事件 - 只是不起作用,我不知道是爲什麼。
回調確實獲得焦點,在/集中了執行(好老的print語句證明),但我從來曾經得到由回調檢測(點擊按鈕的按鍵任何滾輪活動/釋放你也不工作)。
我試圖通過
- 使用函數指針和分配使用的回調函數(我認爲這是應該做的事)
g_signal_connect (mywidget, "event",..)
從foo_new
或foo_init
掛鉤到事件信號
也沒有工作。
的Foo
INIT:
foo_init (Foo *self)
{
GtkWidget *widget = GTK_WIDGET (self);
gtk_widget_set_has_window (widget, FALSE);
self->priv = FOO_GET_PRIVATE (self);
gtk_widget_add_events (widget, GDK_ALL_EVENTS_MASK);
g_assert ((gtk_widget_get_events (widget) & GDK_SCROLL_MASK) != 0); //just fine
/* added some stuff I also tried but did not work */
gtk_widget_set_sensitive (widget, TRUE);
gtk_widget_set_can_focus (widget, TRUE);
gtk_widget_grab_focus (widget);
...
我怎樣才能讓我的小部件的所有事件?
分配widget_class->key_press_event = my_handler_callback;
實際上按預期工作,我得到我按下鍵,但非常相同的widget_class->button_press_event = my_handler_callback;
或widget_class->scroll_event = my_handler_callback;
分配不工作!
widget_class->key_press_event = my_handler_callback; // works
widget_class->key_release_event = my_handler_callback; // works
widget_class->button_press_event = my_handler_callback; // NOT
widget_class->button_release_event = my_handler_callback; // NOT
widget_class->scroll_event = my_handler_callback; // NOT
這讓我懷疑。
要接收該信號,關聯到插件的GdkWindow需要 啓用GDK_BUTTON_PRESS_MASK掩模。
是否有必要在gtk_widget_add_events
「作品」之前實現小部件...?
更新:試過gtk_widget_show_all
之後調用gtk_widget_add_events
。不用找了。
更新:完全可編譯例子
#ifndef __FOO_H__
#define __FOO_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define FOO_TYPE (foo_get_type())
#define FOO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE, Foo))
#define FOO_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), FOO_TYPE, Foo const))
#define FOO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), FOO_TYPE, FooClass))
#define FOO_IS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), FOO_TYPE))
#define FOO_IS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), FOO_TYPE))
#define FOO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), FOO_TYPE, FooClass))
typedef struct _Foo Foo;
typedef struct _FooClass FooClass;
typedef struct _FooPrivate FooPrivate;
struct _Foo
{
GtkWidget parent;
FooPrivate *priv;
};
struct _FooClass
{
GtkWidgetClass parent_class;
};
GType foo_get_type (void) G_GNUC_CONST;
Foo *foo_new (void);
G_END_DECLS
#endif /* __FOO_H__ */
#include "foo.h"
gboolean
scroll_hook (GtkWidget *widget, GdkEventScroll *event)
{
g_print ("%p registered a scroll event\n");
return TRUE;
}
#define FOO_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE((object), FOO_TYPE, FooPrivate))
struct _FooPrivate
{
char to_silence_warning;
};
G_DEFINE_TYPE (Foo, foo, GTK_TYPE_WIDGET)
static void
foo_finalize (GObject *object)
{
G_OBJECT_CLASS (foo_parent_class)->finalize (object);
}
static void
foo_class_init (FooClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = foo_finalize;
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
widget_class->scroll_event = scroll_hook;
g_type_class_add_private (object_class, sizeof (FooPrivate));
}
static void
foo_init (Foo *self)
{
self->priv = FOO_GET_PRIVATE (self);
gtk_widget_set_has_window(GTK_WIDGET(self), FALSE);
}
Foo *
foo_new()
{
return g_object_new (FOO_TYPE, NULL);
}
#include <gtk/gtk.h>
#include "foo.h"
#include <stdlib.h>
gboolean
chicken_out (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
g_print ("bye");
gtk_main_quit();
return TRUE;
}
int
main (int argc, char *argv[])
{
GtkWidget *window;
Foo *my;
int i;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
my = foo_new();
gtk_container_add (GTK_CONTAINER (window), GTK_WIDGET (my));
gtk_widget_show_all (window);
gtk_widget_add_events (GTK_WIDGET (my), GDK_ALL_EVENTS_MASK);
g_assert ((gtk_widget_get_events (GTK_WIDGET (my)) & GDK_SCROLL_MASK) != 0);
g_signal_connect (window, "delete-event", G_CALLBACK(chicken_out), NULL);
gtk_main();
return EXIT_SUCCESS;
}
使用
gcc `pkg-config --cflags --libs gtk+-3.0` -I. ./foo.c ./foo_test.c -o foo.bin
編譯(當然,所有文件都在你的CWD)
作爲開始使用的主要來源,我起訴了@ptomato爲gtk3定製的小部件教程http://ptomato.name/advanced-gtk-techniques/html/custom-container.html – drahnr