You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gtk3 Python环境下为右键上下文菜单关联GMenuModel动作的问题

Gtk3 Python环境下为右键上下文菜单关联GMenuModel动作的问题

嘿,我看了你的代码,问题其实很明确:你的右键菜单能正常显示,但选项都是灰的,是因为从GMenuModel创建的Gtk.Menu没有关联到应用的动作组,找不到app.option1这些动作的实现,所以才会置灰不可用。

给你几个具体的修改点,改完就能正常使用了:

1. 给上下文菜单绑定应用动作组

在AppWindow的__init__方法里,创建完self.context_menu之后,加一行代码,把应用的动作组和菜单里的app前缀关联起来:

# 把应用的动作组插入到菜单,对应菜单里动作的"app"前缀
self.context_menu.insert_action_group("app", self.get_application())

这一步是关键,菜单里的动作写的是app.option1,其中app是动作组的前缀,我们需要告诉菜单这个前缀对应的是你的应用实例(它是动作的载体),这样菜单才能找到对应的动作实现。

2. 删掉多余的错误代码

在Application的do_startup方法里,有一行多余的代码:

self.set_app_menu(builder.get_object("app-menu"))

你的MENU_XML里根本没有定义app-menu这个菜单,这行代码运行时会报错,直接删掉就行。

3. 可选:去掉冗余的显示代码

在on_right_click方法里,self.context_menu.show_all()其实是多余的,popup_at_pointer会自动处理菜单的显示,删掉这行也不影响功能。

修改后的完整代码

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"))
        # 新增:关联应用的动作组到菜单
        self.context_menu.insert_action_group("app", self.get_application())

        # 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_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)
        # 删掉了多余的set_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()

原理补充一下

GMenuModel里的动作标识符(比如app.option1)是[动作组前缀].[动作名]的格式,你已经在应用里注册了option1和option2这两个动作,但菜单不知道app这个前缀对应的是哪个对象,所以通过insert_action_group把应用实例和app前缀绑定后,菜单就能正确找到动作的实现,自然就可以点击了。

现在运行修改后的代码,右键点击窗口里的标签,菜单选项就可以正常触发对应的打印输出啦!

备注:内容来源于stack exchange,提问作者DobbyTheElf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 18:14:36