0

我正在使用gtk-rs并希望能够检测到何时按下任何键。

从一些在线搜索来看,在 C 中执行此操作的方法似乎是使用gtk_widget_add_events然后g_signal_connect. 这个答案有一个很好的解释。

在 Rust 中,我可以调用Widget::add_events. 我还找到了g_signal_connect_*. 但是,这些函数是unsafe未记录的,并且似乎将 C 类型作为参数。

我的问题是:

  1. 为了使用gobject_sys::g_signal_connect_closure,我如何创建一个GObjectGClosure. 在锈?rust 结构和闭包可以转换成那个吗?
  2. 是否有更好、更惯用的方式来监听关键事件?我很难相信做这样一个基本的事情需要这样一个深奥的界面。我已经看到对特定键盘快捷键或键盘加速组的一些支持,但我无法找到任何文档或示例来监听按键事件。
4

1 回答 1

1

我想到了。

谢谢@Jmb,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();
于 2021-03-09T18:52:08.150 回答