如何使用XML在PyGtk的菜单中添加带图片的功能按钮
问题原因
<menu>标签属于GMenu模型的XML规范,仅支持<menu>、<section>、<item>三类子节点,直接写<button>属于语法错误,会触发第一个报错。- 绑定了
menu_model的Gtk.MenuButton生成的Popover内部已经封装了专门渲染菜单的GtkStack容器,该容器的页面由GTK自动管理,你直接往Stack里添加的控件不会被渲染到可见页面,因此看不到效果。
可行方案
方案1:给GMenu菜单项添加图标(最小改动)
如果只是需要菜单项带图标,不需要额外独立按钮,直接通过GMenu属性配置即可:
- 代码初始化部分开启菜单图标显示:
Gtk.Settings.get_default().set_property("gtk-menu-images", True)
- 修改MENU_XML,给目标菜单项添加
icon属性:
<interface> <menu id="app-popover"> <section> <item> <attribute name="label">Test action</attribute> <attribute name="action">app.sample-action</attribute> <attribute name="icon">document-print-symbolic</attribute> </item> </section> </menu> </interface>
生成的菜单项会自带指定图标,样式和标准按钮一致,原有动作绑定逻辑无需修改。
方案2:自定义Popover容器(支持任意控件组合)
如果需要在菜单外添加独立的带图按钮,手动构建Popover完全自定义内容即可:
修改AppWindow.__init__代码如下:
class AppWindow(Gtk.ApplicationWindow): def __init__(self, *args, **kwargs): Gtk.ApplicationWindow.__init__(self, *args, **kwargs) # 读取原有菜单模型 builder = Gtk.Builder.new_from_string(MENU_XML, -1) popover_menu = builder.get_object("app-popover") # 手动创建Popover容器 self.popover = Gtk.Popover() popover_box = Gtk.VBox(spacing=6) self.popover.add(popover_box) # 添加自定义带图按钮 print_btn = Gtk.Button.new_from_icon_name("document-print-symbolic", Gtk.IconSize.BUTTON) print_btn.set_label("打印") # 绑定点击动作,也可以关联Gio.Action print_btn.connect("clicked", lambda _: print("打印按钮触发")) popover_box.pack_start(print_btn, False, False, 0) # 添加分隔线和原有菜单项 popover_box.pack_start(Gtk.Separator(orientation=Gtk.Orientation.HORIZONTAL), False, False, 0) original_menu = Gtk.Menu.new_from_model(popover_menu) popover_box.pack_start(original_menu, False, False, 0) # 绑定到MenuButton self.popover_button = Gtk.MenuButton() self.popover_button.set_popover(self.popover) self.box = Gtk.VBox() self.box.pack_start(self.popover_button, False, False, 0) self.add(self.box) self.maximize() self.show_all()
该方式可以自由组合Popover内的所有控件,灵活性最高。
内容的提问来源于stack exchange,提问作者Sylvester is on codidact.com
相关产品推荐
相关产品推荐

