簡體   English   中英

GTKmm 彈出菜單項在與 treeview 一起使用時不突出顯示

[英]GTKmm popover menu items not highlighting when used with treeview

下午好,

我正在嘗試將彈出上下文菜單集成到 GTKmm 4 中的 treeview 小部件。

我已經成功地顯示了菜單,並在單擊上下文菜單選項時調用了相應的操作,但是,我發現當鼠標懸停在菜單項上時,菜單項沒有突出顯示。

顯示我所見內容的 GIF 在這里:

演示

但是,如果使用相同的代碼,我將菜單和操作組附加到另一個小部件(例如按鈕或 window 本身),所有工作都會按預期進行並且選項會正確突出顯示。

下面是一個最小可重現示例的代碼。

當我繞着這個圈子轉圈時,有人可以幫忙嗎?

#include <gtkmm.h>

class Window : public Gtk::Window {

public:
    Window() {
        list_store_ = Gtk::ListStore::create(model_);

        auto row = *(list_store_->append());
        row[model_.id] = 1;
        row[model_.name] = "Example 1";

        row = *(list_store_->append());
        row[model_.id] = 2;
        row[model_.name] = "Example 2";

        treeview_.set_hexpand(true);
        treeview_.set_vexpand(true);
        treeview_.set_model(list_store_);
        treeview_.append_column("ID", model_.id);
        treeview_.append_column("Name", model_.name);

        Glib::RefPtr<Gio::Menu> gmenu = Gio::Menu::create();
        gmenu->append("_Edit", "popup.edit");
        gmenu->append("_Remove", "popup.remove");

        menu_.set_parent(treeview_);
        menu_.set_menu_model(gmenu);
        menu_.set_has_arrow(false);

        Glib::RefPtr<Gio::SimpleActionGroup> action_group = Gio::SimpleActionGroup::create();
        action_group->add_action("edit", sigc::mem_fun(*this, &Window::on_popup_edit));
        action_group->add_action("remove", sigc::mem_fun(*this, &Window::on_popup_remove));

        treeview_.insert_action_group("popup", action_group);

        Glib::RefPtr<Gtk::GestureClick> gesture = Gtk::GestureClick::create();
        gesture->set_button(GDK_BUTTON_SECONDARY);
        gesture->signal_pressed().connect(sigc::mem_fun(*this, &Window::on_popup_button_pressed));
        treeview_.add_controller(gesture);

        set_child(treeview_);
    }

    ~Window() override {

    }

private:
    class ExampleModel : public Gtk::TreeModel::ColumnRecord {
    public:

        ExampleModel() {
            add(id);
            add(name);
        }

        Gtk::TreeModelColumn<int> id;
        Gtk::TreeModelColumn<Glib::ustring> name;
    };

    void on_popup_button_pressed(int, double x, double y) {
        int cx, cy;
        treeview_.convert_widget_to_bin_window_coords(x, y, cx, cy);

        Gtk::TreeModel::Path path;
        treeview_.get_path_at_pos(cx, cy, path);
        if (!path) {
            return;
        }

        const Gdk::Rectangle rect(x, y, 1, 1);
        menu_.set_pointing_to(rect);
        menu_.popup();
    }

    void on_popup_edit() { /* Implementation here */ }
    void on_popup_remove() { /* Implementation here */ }

    Gtk::TreeView treeview_;
    ExampleModel model_;
    Glib::RefPtr<Gtk::ListStore> list_store_;
    Gtk::PopoverMenu menu_;
};

int main(int argc, char** argv) {
    auto app = Gtk::Application::create("com.example.treeview");

    return app->make_window_and_run<Window>(argc, argv);
}

好的,所以我最近有時間回到這個項目。 這次我想我會嘗試使用 gtk4-rs crate 在 Rust 中重寫它,看看是否會發生同樣的事情,它確實發生了!

我設法通過將 TreeView 包裝在ScrolledWindow內,然后針對 ScrolledView 而不是 TreeView 設置菜單來解決此問題。在on_popup_button_pressed function內,我仍然能夠確定被單擊的路徑/項目.

更新后的代碼(雖然未經測試 - 因為該項目現在改為在 Rust 中編寫)如下:

#include <gtkmm.h>

class Window : public Gtk::Window {

public:
    Window() {
        list_store_ = Gtk::ListStore::create(model_);

        auto row = *(list_store_->append());
        row[model_.id] = 1;
        row[model_.name] = "Example 1";

        row = *(list_store_->append());
        row[model_.id] = 2;
        row[model_.name] = "Example 2";

        treeview_.set_hexpand(true);
        treeview_.set_vexpand(true);
        treeview_.set_model(list_store_);
        treeview_.append_column("ID", model_.id);
        treeview_.append_column("Name", model_.name);

        scrolled_window_.set_child(treeview_);

        Glib::RefPtr<Gio::Menu> gmenu = Gio::Menu::create();
        gmenu->append("_Edit", "popup.edit");
        gmenu->append("_Remove", "popup.remove");

        menu_.set_parent(scrolled_window_);
        menu_.set_menu_model(gmenu);
        menu_.set_has_arrow(false);

        Glib::RefPtr<Gio::SimpleActionGroup> action_group = Gio::SimpleActionGroup::create();
        action_group->add_action("edit", sigc::mem_fun(*this, &Window::on_popup_edit));
        action_group->add_action("remove", sigc::mem_fun(*this, &Window::on_popup_remove));

        scrolled_window.insert_action_group("popup", action_group);

        Glib::RefPtr<Gtk::GestureClick> gesture = Gtk::GestureClick::create();
        gesture->set_button(GDK_BUTTON_SECONDARY);
        gesture->signal_pressed().connect(sigc::mem_fun(*this, &Window::on_popup_button_pressed));
        scrolled_window_.add_controller(gesture);

        set_child(scrolled_window_);
    }

    ~Window() override {

    }

private:
    class ExampleModel : public Gtk::TreeModel::ColumnRecord {
    public:

        ExampleModel() {
            add(id);
            add(name);
        }

        Gtk::TreeModelColumn<int> id;
        Gtk::TreeModelColumn<Glib::ustring> name;
    };

    void on_popup_button_pressed(int, double x, double y) {
        int cx, cy;
        treeview_.convert_widget_to_bin_window_coords(x, y, cx, cy);

        Gtk::TreeModel::Path path;
        treeview_.get_path_at_pos(cx, cy, path);
        if (!path) {
            return;
        }

        const Gdk::Rectangle rect(x, y, 1, 1);
        menu_.set_pointing_to(rect);
        menu_.popup();
    }

    void on_popup_edit() { /* Implementation here */ }
    void on_popup_remove() { /* Implementation here */ }

    Gtk::TreeView treeview_;
    Gtk::ScrolledWindow scrolled_window_;
    ExampleModel model_;
    Glib::RefPtr<Gtk::ListStore> list_store_;
    Gtk::PopoverMenu menu_;
};

int main(int argc, char** argv) {
    auto app = Gtk::Application::create("com.example.treeview");

    return app->make_window_and_run<Window>(argc, argv);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM