0

我已经(某种程度上)复制了(但做了一些修改)GTKmm 键盘事件教程中的示例。(链接

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。

4

1 回答 1

0
  1. 首先连接您的处理程序。

    _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)是否为 ONLY GDK_CONTROL_MASK

代码:

#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());
}
于 2018-06-18T13:21:38.810 回答