将 GMenuModel 链接到 Python Gtk3 中上下文菜单的操作

问题描述 投票:0回答:1

我使用 Gtk3 和 Gtk.Builder 构建了一个应用程序,并使用 GMenuModel 作为菜单。到目前为止,一切都很好。现在我想添加上下文(即右键单击)菜单。

菜单本身出现了,但由于我似乎无法找到链接操作的正确咒语,因此它们总是出现幻影。这是我的玩具代码示例:

import sys
import os
import gi

gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gio, Gtk

_curr_dir = os.path.split(__file__)[0]

# This would typically be its own file
MENU_XML = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <menu id="context_menu">
    <section>
      <item>
        <attribute name="label" translatable="yes">Option 1</attribute>
        <attribute name="action">app.option1</attribute>
      </item>
      <item>
        <attribute name="label" translatable="yes">Option 2</attribute>
        <attribute name="action">app.option2</attribute>
      </item>
    </section>
  </menu>
</interface>
"""


class AppWindow(Gtk.ApplicationWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.set_default_size(400, 300)
        self.connect("destroy", Gtk.main_quit)

        # Load the UI from the Glade file
        builder = Gtk.Builder()
        builder = Gtk.Builder.new_from_string(MENU_XML, -1)

        # Get the context menu defined in the XML
        self.context_menu = Gtk.Menu.new_from_model(builder.get_object("context_menu"))

        # Add a simple label
        self.label = Gtk.Label(label="Right-click to open context menu")
        self.add(self.label)
        self.label.show()
        # Connect the button press event (right-click)
        self.connect("button-press-event", self.on_right_click)

    def on_right_click(self, widget, event):
        # Check if it's the right-click (button 3)
        if event.button == 3:
            # Show the context menu
            # self.context_menu.popup(None, None, None, None, event.button, event.time)
            self.context_menu.show_all()
            self.context_menu.popup_at_pointer(event)


class Application(Gtk.Application):

    def __init__(self, *args, **kwargs):
        super().__init__(
            *args,
            application_id="org.example.myapp",
            **kwargs
        )
        self.window = None

    def do_startup(self):
        Gtk.Application.do_startup(self)
        action = Gio.SimpleAction.new("option1", None)
        action.connect("activate", self.on_option1_activated)
        self.add_action(action)
        action = Gio.SimpleAction.new("option2", None)
        action.connect("activate", self.on_option2_activated)
        self.add_action(action)
        builder = Gtk.Builder.new_from_string(MENU_XML, -1)
        self.set_app_menu(builder.get_object("app-menu"))

    def do_activate(self):

        # We only allow a single window and raise any existing ones
        if not self.window:

            # Windows are associated with the application
            # when the last one is closed the application shuts down
            self.window = AppWindow(application=self, title="Main Window")

        self.window.present()

    def on_quit(self, action, param):
        self.quit()

    def on_option1_activated(self, widget):
        print("Option 1 selected")

    def on_option2_activated(self, widget):
        print("Option 2 selected")


if __name__ == "__main__":
    app = Application()
    app.run()

如何链接操作以便可以使用菜单?

python gtk3
1个回答
0
投票

这是我当前的解决方法 - 不是我喜欢的答案,因为它不直接使用操作:

import sys
import os
import gi

gi.require_version("Gtk", "3.0")
from gi.repository import GLib, Gio, Gtk

_curr_dir = os.path.split(__file__)[0]

# This would typically be its own file
MENU_XML = """
<?xml version="1.0" encoding="UTF-8"?>
<interface>
  <object class="GtkMenu" id="context_menu">
    <child>
      <object class="GtkMenuItem" id="option1">
        <property name="label">Option 1</property>
        <signal name="activate" handler="on_option1_activated"/>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem" id="option2">
        <property name="label">Option 2</property>
        <signal name="activate" handler="on_option2_activated"/>
      </object>
    </child>
  </object>
</interface>
"""


class RightClickMenu(Gtk.Window):
    def __init__(self):
        super().__init__(title="Right-Click Context Menu")

        self.set_default_size(400, 300)
        self.connect("destroy", Gtk.main_quit)

        # Load the UI from the Glade file
        builder = Gtk.Builder()
        builder = Gtk.Builder.new_from_string(MENU_XML, -1)

        # Get the context menu defined in the XML
        self.context_menu = builder.get_object("context_menu")

        # Connect the signals for menu item activation
        builder.connect_signals(self)

        # Add a simple label
        self.label = Gtk.Label(label="Right-click to open context menu")
        self.add(self.label)

        # Connect the button press event (right-click)
        self.connect("button-press-event", self.on_right_click)

    def on_right_click(self, widget, event):
        # Check if it's the right-click (button 3)
        if event.button == 3:
            # Show the context menu
            # self.context_menu.popup(None, None, None, None, event.button, event.time)
            self.context_menu.show_all()
            self.context_menu.popup_at_pointer(event)

    def on_option1_activated(self, widget):
        print("Option 1 selected")

    def on_option2_activated(self, widget):
        print("Option 2 selected")

if __name__ == "__main__":
    win = RightClickMenu()
    win.show_all()
    Gtk.main()
© www.soinside.com 2019 - 2024. All rights reserved.