我正在使用
gtk-rs
并且希望能够检测何时按下任意键。
根据网上的一些搜索,似乎在 C 中执行此操作的方法是先使用
gtk_widget_add_events
,然后使用 g_signal_connect
。 这个答案有很好的解释。
Widget::add_events
。我还找到了 g_signal_connect_*
的几个定义。但是,这些函数unsafe
,没有文档记录,并且似乎采用 C 类型作为参数。
我的问题是:
gobject_sys::g_signal_connect_closure
,如何创建GObject
和GClosure
。在铁锈中? Rust 结构和闭包可以转换成那个吗?我明白了。
Widget::connect
是正确的选择。但是,该函数没有文档记录,并且有一些非常奇怪的类型。以下是我如何使用它的方法:
window
.connect("key_press_event", false, |values| {
// "values" is a 2-long slice of glib::value::Value, which wrap G-types
// You can unwrap them if you know what type they are going to be ahead of time
// values[0] is the window and values[1] is the event
let raw_event = &values[1].get::<gdk::Event>().unwrap().unwrap();
// You have to cast to the correct event type to access some of the fields
match raw_event.downcast_ref::<gdk::EventKey>() {
Some(event) => {
println!("key value: {:?}", std::char::from_u32(event.get_keyval()));
println!("modifiers: {:?}", event.get_state());
},
None => {},
}
// You need to return Some() of a glib Value wrapping a bool
let result = glib::value::Value::from_type(glib::types::Type::Bool);
// I can't figure out how to actually set the value of result
// Luckally returning false is good enough for now.
Some(result)
})
.unwrap();
在寻找同一问题的解决方案时发现了这个问题,但无法像这个答案那样工作。
然后我找到了另一种实现按键事件处理程序的方法:
EventControllerKey
,您可以在其上连接到 key-pressed
、key-released
和 modifiers
信号。然后你只需在窗口上注册 EventControllerKey 即可。
最小示例:
// ... Application setup
let window = gtk::ApplicationWindow::builder()
.application(app)
.build();
let event_controller = gtk::EventControllerKey::new();
event_controller.connect_key_pressed(|_, key, _, _| {
match key {
gdk::Key::Escape => {
std::process::exit(0);
}
_ => (),
}
glib::Propagation::Proceed
});
window.add_controller(event_controller);
window.present();
我将其与
gtk4
一起使用。
希望有人觉得这很有用。