【问题标题】:gtk-rs: how to listen for keyboard eventsgtk-rs:如何监听键盘事件
【发布时间】:2021-03-11 01:53:12
【问题描述】:

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

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

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

我的问题是:

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

【问题讨论】:

  • 但是,这些功能是不安全的 我想知道,ùnsafe 对你来说意味着什么?

标签: rust gtk3 gtk-rs


【解决方案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();

【讨论】:

  • 两个注意事项:在较新的gtk-rs 绑定中,getter 前面不再有get_。因此,您将使用keyval() 而不是get_keyval() 等。此外,要从某事物构造一个glib 值,只需对该事物执行.to_value()。所以要返回 true,你会做(true).to_value()
猜你喜欢
  • 2018-04-15
  • 2015-08-14
  • 2019-10-01
  • 1970-01-01
  • 2014-09-01
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多