X事件信号

Widget有一些对应底层X-Windows事件的特殊信号。它们具有_event后缀。例如:Widget::signal_button_press_event()

当有些事情你无法使用常规信号完成时,你可能会发现X事件信号非常有用。例如:Gtk::Buttonclicked信号不会发送鼠标指针的坐标,而button_press_event信号会。X事件也用于处理按键。

这些信号的行为有所不同。它们的信号处理函数将通过返回值指示有没有完全处理事件。如果返回值为false,则gtkmm将会把事件再次发送到下一个信号处理函数。如果返回值为true则不再传播信号不再调用其他的信号处理函数。

处理X事件不会影响部件的其他信号。如果你处理Gtk::Buttonbutton_press_event信号,你依旧可以得到clicked信号。这两个信号将几乎于同一时间被发出。

这是一个简单的例子:

bool on_button_press(GdkEventButton* event);
Gtk::Button button("label");
button.signal_button_press_event().connect( sigc::ptr_fun(&on_button_press) );

当鼠标悬停在鼠标上方并按下鼠标按钮时,on_button_press()将被调用。

GdkEventButton是一个包含事件参数的结构体,其中包含按下按钮时鼠标指针的坐标等一系列信息。对于不同的事件,有不同的GdkEvent结构体类型与之对应。

B.6.1. 信号处理函数序列

默认情况下,你的信号处理函数将于所有之前连接到信号的信号处理函数之后被调用。但是这对于X事件信号可能会出问题。例如,现有的信号处理函数或默认信号处理函数如果返回了true将会停止事件传播,这时候你的信号处理函数就不会被调用。你可以指定可选参数afterfalse,这样你的信号处理函数就总是会被调用。例如:

button.signal_button_press_event().connect( sigc::ptr_fun(&on_mywindow_button_press), false );

这个事件将首先被发送到发生事件的部件中。如果该部件的所有信号处理函数都返回false。则该信号将被传播到部件的父部件中。如果后续没有人处理事件,信号会一直传播到顶级窗口部件。