GTKmm应用:Gdk按键信号未触发

时间:2018-02-06 16:14:01

标签: gtkmm gtkmm3

我(有点)复制了(但有一些修改)关于键盘事件的GTKmm教程中的示例。 (link

https://developer.gnome.org/gtkmm-tutorial/stable/sec-keyboardevents-overview.html.en#keyboardevents-simple-example

这是我的代码:

#include <gtkmm/application.h>
#include <gtkmm/window.h>
#include <gtkmm/textview.h>

#include <iostream>

class MainWindow
{
    public:

    MainWindow()
    {
        _window_.set_default_size(600, 400);
        _window_.add(_textview_);

        Glib::RefPtr<Gtk::TextBuffer> textbuffer_rp{_textview_.get_buffer()};
        textbuffer_rp->set_text("some text here");
        _textview_.set_monospace();

        _window_.add_events(Gdk::KEY_PRESS_MASK);

        _window_.show_all_children();
    }

    Gtk::Window &get_window()
    {
        return _window_;
    }

    protected:

    bool on_key_press_event(GdkEventKey* event)
    {
        std::cout << "some keypress event" << std::endl; 

        if
        (
            (event->keyval == GDK_KEY_H) &&
            ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK) == GDK_CONTROL_MASK))
        )
        {
            std::cout << "Hello world!" << std::endl;
        }

        if
        (
            (event->keyval == GDK_KEY_C) &&
            ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK) == GDK_CONTROL_MASK))
        )
        {
            signal_textview_CTRL_C();
        }
        else if
        ( 
            (event->keyval == GDK_KEY_V) &&
            ((event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK) == GDK_CONTROL_MASK))
        )
        {
            signal_textview_CTRL_V();
        }
        else
        {
            std::cout << "unhandled key" << std::endl;
        }

        return true;
    }

    void signal_textview_CTRL_C()
    {
        _text_register_0_ = "some text gets put here";
    }

    void signal_textview_CTRL_V()
    {
        Glib::RefPtr<Gtk::TextBuffer> textbuffer_rp{_textview_.get_buffer()};
        textbuffer_rp->set_text(_text_register_0_);
    }

    private:

    Gtk::Window _window_;
    Gtk::TextView _textview_;

    Glib::ustring _text_register_0_;

};

int main(int argc, char *argv[])
{
    auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");

    MainWindow mainwindow;

    return app->run(mainwindow.get_window());
}

然而它无法正常工作 - 按下按键顺序CTRL-C,CTRL-V,CTRL-H时,没有任何信号事件出现。

我想我已经从代码中剥离了所有不相关的东西,所以这应该是一个有效的MWE。

1 个答案:

答案 0 :(得分:0)

  1. Connect您的处理程序为第一个。

    _window_.signal_key_press_event().connect(sigc::mem_fun(*this, &MainWindow::on_key_press_event), false);
    
  2. 返回false_textview_获取密钥。

  3. 你的条件是矛盾的。

    GDK_KEY_H是shift + h的关键词。然后检查(event->state & (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK) == GDK_CONTROL_MASK)。您问state(我们知道GDK_SHIFT_MASK}是否只有GDK_CONTROL_MASK

  4. 代码:

    #include <gtkmm/application.h>
    #include <gtkmm/window.h>
    #include <gtkmm/textview.h>
    #include <iostream>
    
    class MainWindow
    {
    public:
        MainWindow()
        {
            _window_.set_default_size(600, 400);
            _window_.add(_textview_);
    
            Glib::RefPtr<Gtk::TextBuffer> textbuffer_rp{_textview_.get_buffer()};
            textbuffer_rp->set_text("some text here");
            _textview_.set_monospace();
    
            _window_.add_events(Gdk::KEY_PRESS_MASK);
            _window_.signal_key_press_event().connect(sigc::mem_fun(*this, &MainWindow::on_key_press_event), false);
    
            _window_.show_all_children();
        }
    
        Gtk::Window &get_window()
        {
            return _window_;
        }
    
    protected:
    
        bool on_key_press_event(GdkEventKey* event)
        {
            std::cout << "some keypress event " << std::hex<<event->keyval<<" "<<std::hex<<event->state<<std::endl; 
    
            if
                (
                 (event->keyval == GDK_KEY_h) &&
                 (event->state & GDK_CONTROL_MASK)
                 )
            {
                std::cout << "Hello world!" << std::endl;
                return true;
            }
    
            if
                (
                 (event->keyval == GDK_KEY_c) &&
                 (event->state & GDK_CONTROL_MASK)
                 )
            {
                std::cout<<"ctrl c"<<std::endl;
                signal_textview_CTRL_C();
                return true;
            }
            else if
                ( 
                 (event->keyval == GDK_KEY_v) &&
                 (event->state & GDK_CONTROL_MASK)
                  )
            {
                std::cout<<"ctrl v"<<std::endl;
                signal_textview_CTRL_V();
                return true;
            }
            else
            {
                std::cout << "unhandled key" << std::endl;
            }
    
            return false;
        }
    
        void signal_textview_CTRL_C()
        {
            _text_register_0_ = "some text gets put here";
        }
    
        void signal_textview_CTRL_V()
        {
            Glib::RefPtr<Gtk::TextBuffer> textbuffer_rp{_textview_.get_buffer()};
            textbuffer_rp->set_text(_text_register_0_);
        }
    
    private:
    
        Gtk::Window _window_;
        Gtk::TextView _textview_;
    
        Glib::ustring _text_register_0_;
    
    };
    
    int main(int argc, char *argv[])
    {
        auto app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");
    
        MainWindow mainwindow;
    
        return app->run(mainwindow.get_window());
    }