5

我一直在使用 gtkmm 编写一个 Gtk+ 应用程序,并且我正在尝试添加一个调用回调的全局键盘快捷键。不幸的是,Gtk::AccelGroup 的 connect() 方法在 gtkmm 中不可用,显然是故意的,因为您可以使用 ActionGroups 进行连接...

无论如何,我有以下代码:

actions_= Gtk::ActionGroup::create();
actions_->set_accel_group(Gtk::AccelGroup::create());

actions_->add(
    Gtk::Action::create("new"), Gtk::AccelKey("<control>n"),
    sigc::mem_fun(this, &Window::new_buffer_thing)
);

_gtk_window().add_accel_group(actions_->get_accel_group());

它编译并运行没有警告,但键盘快捷键什么也不做。我一直在摆弄这个几个小时,所以任何帮助或指导将不胜感激!

我在做一些明显错误的事情吗?为什么加速器不工作?

4

2 回答 2

1

回答这个问题有点晚了,但我今天一直在解决同样的问题,即使在不同的环境中:python,gtk2。

据我从本教程的一些实验中了解到,除非与工具箱或菜单栏相关联,否则操作不会处于活动状态。太糟糕了,就这样做,将工具栏打包到一个 VBox 中,并使其不可见,如下所示:

actiongroup = gtk.ActionGroup('window-clip-actions')
accelgroup = gtk.AccelGroup()
fake_toolbar = gtk.Toolbar()
view.get_window().add_accel_group(accelgroup)
view.get_window().get_content_area().pack_start(fake_toolbar)
for shortcut, cb in (('<ctrl><shift>c', self.on_window_clip_copy),
                     ('<ctrl><shift>v', self.on_window_clip_paste)):
    action = gtk.Action(shortcut, shortcut, 'clip-action', None)
    actiongroup.add_action_with_accel(action, shortcut)
    action.connect("activate", cb)
    action.set_accel_group(accelgroup)
    action.connect_accelerator()
    toolitem = action.create_tool_item()
    fake_toolbar.insert(toolitem, -1)
fake_toolbar.set_visible(False)

知道相同的方法是否会帮助 OP 会很有趣。

于 2018-01-18T01:27:16.277 回答
0

在阅读了 marioomo 的回答后,这是我为 gtkmm3 实现的隐藏菜单栏。

快捷键加速器适用于隐藏菜单栏:)

#include <iostream>
#include <gtkmm.h>

using Gtk::Application;
using Gtk::Box;
using Gtk::Builder;

using Gio::SimpleActionGroup;

using std::cout;

class ExampleWindow : public Gtk::Window
{
public:
    ExampleWindow(const Glib::RefPtr<Application>& app);

private:
    void on_action_file_new();
    // for hidden menubar
    void on_action_secret();

    Box box1;
    Box box2;

    Glib::RefPtr<Builder>           builder;
    Glib::RefPtr<SimpleActionGroup> actiongroup;
};

ExampleWindow::ExampleWindow(const Glib::RefPtr<Application>& app)
    : box1(Gtk::ORIENTATION_VERTICAL)
    , box2(Gtk::ORIENTATION_VERTICAL)
{
    set_title("Menubar test");
    set_default_size(400, 200);

    add(box1);

    box1.add(box2);

    //Define the actions:
    actiongroup = Gio::SimpleActionGroup::create();

    actiongroup->add_action("new"   , sigc::mem_fun(*this, &ExampleWindow::on_action_file_new));
    actiongroup->add_action("secret", sigc::mem_fun(*this, &ExampleWindow::on_action_secret));

    insert_action_group("example"       , actiongroup);
    insert_action_group("example-hidden", actiongroup);

    builder = Gtk::Builder::create();

    app->set_accel_for_action("example.new"          , "<Primary>n");
    app->set_accel_for_action("example-hidden.secret", "<Primary>m");

    const char *visible_ui_info =
        "<interface>"
        "  <menu id='visible-menubar'>"
        "    <submenu>"
        "      <attribute name='label' translatable='yes'>_File</attribute>"
        "      <section>"
        "        <item>"
        "          <attribute name='label' translatable='yes'>_New</attribute>"
        "          <attribute name='action'>example.new</attribute>"
        "          <attribute name='accel'>&lt;Primary&gt;n</attribute>"
        "        </item>"
        "      </section>"
        "    </submenu>"
        "  </menu>"
        "</interface>";
    
    const char *hidden_ui_info = 
        "<interface>"
        "  <menu id='hidden-menubar'>"
        "    <submenu>"
        "      <attribute name='label' translatable='yes'>_Secret</attribute>"
        "      <section>"
        "        <item>"
        "          <attribute name='label' translatable='yes'>_Key</attribute>"
        "          <attribute name='action'>example-hidden.secret</attribute>"
        "          <attribute name='accel'>&lt;Primary&gt;m</attribute>"
        "        </item>"
        "      </section>"
        "    </submenu>"
        "  </menu>"
        "</interface>";

    builder->add_from_string(visible_ui_info);
    builder->add_from_string(hidden_ui_info);

    // Get the visible menubar:
    auto object1  = builder->get_object("visible-menubar");
    auto gmenu1   = Glib::RefPtr<Gio::Menu>::cast_dynamic(object1);
    auto menubar1 = Gtk::make_managed<Gtk::MenuBar>(gmenu1);
    box1.pack_start(*menubar1, Gtk::PACK_SHRINK);

    // Get the hidden menubar
    auto object2  = builder->get_object("hidden-menubar");
    auto gmenu2   = Glib::RefPtr<Gio::Menu>::cast_dynamic(object2);
    auto menubar2 = Gtk::make_managed<Gtk::MenuBar>(gmenu2);
    box2.pack_start(*menubar2, Gtk::PACK_SHRINK);

    show_all_children();
    box2.hide();
}

void ExampleWindow::on_action_file_new()
{
    cout << "New menu item was selected.\n";
}

void ExampleWindow::on_action_secret()
{
    cout << "Secret menu item was selected.\n";
}

int main()
{
    auto app = Application::create("org.gtkmm.example");

    ExampleWindow window(app);

    return app->run(window);
}
于 2020-10-12T05:40:40.507 回答