【问题标题】:How to populate a GtkMenu with some GtkMenuItem and set its parent in Glade?如何用一些 GtkMenuItem 填充 GtkMenu 并在 Glade 中设置其父级?
【发布时间】:2017-08-27 00:50:49
【问题描述】:

Gtk.Toolbar 中,我有一个带有箭头的Gtk.MenuToolButton,我想将Gtk.Menu 与之关联,最好是在Glade 中构建。

我的代码是这样的:

self.menuToolButtonCalculate.set_menu(self.get_object("menuCalculate"))

其中self.menuToolButtonCalculate是通过Gtk.Builder.get_object方法获得的,self是Gtk.Builder的子类的一个实例。

当窗口加载时,程序在终端中显示了一些Gtk/Gdk-CRITICAL 警告,当我点击箭头时程序崩溃了。在显示窗口之前,我还在 Python 代码中填充了 Glade 中定义的 Gtk.Menu,但程序仍然崩溃,所以我现在确定问题不在于菜单为空。

出于测试目的,我用这个替换了该行:

self.menuToolButtonCalculate.set_menu(Gtk.Menu())

程序在加载窗口时仍然在终端中显示Gtk/Gdk-CRITICAL 警告,但是当我单击箭头时程序没有崩溃,它在箭头附近显示一个空的上下文菜单。

这些Gtk/Gdk-CRITICAL 警告是:

(python2.exe:14672): Gtk-CRITICAL **: gtk_widget_set_size_request: assertion 'GTK_IS_WIDGET (widget)' failed

(python2.exe:14672): Gtk-CRITICAL **: gtk_container_add: assertion 'GTK_IS_CONTAINER (container)' failed

(python2.exe:14672): Gdk-CRITICAL **: gdk_window_get_height: assertion 'GDK_IS_WINDOW (window)' failed

(python2.exe:14672): Gtk-CRITICAL **: gtk_widget_reparent: assertion 'priv->parent != NULL' failed

(python2.exe:14672): Gdk-CRITICAL **: gdk_window_get_width: assertion 'GDK_IS_WINDOW (window)' failed

(python2.exe:14672): Gdk-CRITICAL **: gdk_device_get_position_double: assertion 'GDK_IS_DEVICE (device)' failed

我使用安装了最新更新的 Windows 10 Pro x64、安装了最新更新的 MSYS2 和 MSYS2、x86 版本:Python 2.7.13、Glade 3.20 和 GTK+ 3.22。

更新:

简化的测试代码在终端中完美运行,没有崩溃或警告:

example1.glade

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkMenu" id="menu">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
  </object>
  <object class="GtkWindow" id="window1">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkToolbar">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkMenuToolButton" id="menuToolButton">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="label" translatable="yes">__glade_unnamed_2</property>
            <property name="use_underline">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="homogeneous">True</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

example1.py

​​>
# coding=utf-8

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


b = Gtk.Builder()
b.add_from_file("example1.glade")
w = b.get_object("window1")
mtb = b.get_object("menuToolButton")
m = b.get_object("menu")
mtb.set_menu(m)

w.connect("delete-event", Gtk.main_quit)
w.show_all()
Gtk.main()

原来的程序太大了,这里放不下。请告诉我您希望我发布原始代码中的哪些详细信息,以便您帮助我。

更新 2:

在主程序的 Glade .ui 文件中,我定义了 GtkMenu:

<object class="GtkMenu" id="menuCalculate">
  <property name="visible">True</property>
  <property name="can_focus">False</property>
  <property name="tearoff_state">True</property>
  <property name="tearoff_title">Ce dorești să calculez?</property>
</object>

如果我删除最后两个元素(导致程序行为发生变化的元素是tearoff_state

<object class="GtkMenu" id="menuCalculate">
  <property name="visible">True</property>
  <property name="can_focus">False</property>
</object>

当我单击 Glade 文件中声明的 GtkMenuToolButtonGtkMenu)的箭头时,程序不会崩溃,它会打开一个空菜单。

所以问题只是由在 Glade 中创建的 GtkMenu 引起的,它没有父级,这是 tearoff_state 属性所必需的。

  1. 如果这是真的,将GtkMenu 的父级设置为GtkMenuToolButton( 的箭头) 的推荐方法是什么,最好在Glade 中,但至少在代码中?
  2. 据我所知,不可能用 Glade 中的项目填充GtkMenu,因此我必须从代​​码中填充它。这是真的吗?

【问题讨论】:

  • 那么你的意思是当你删除(折旧的)属性tearoff_state它工作正常吗?我不确定是什么问题。
  • 整题集中在题尾的(1)和(2)点。
  • 所以问题是“我可以将 GtkMenu 关联到 glade 中的 GtkMenuToolButton”和“我可以在 glade 中定义填充菜单吗”?
  • 抱歉,我花了一段时间才输入答案
  • .. 还有 ????

标签: python-2.7 gtk3 glade msys2 gtkbuilder


【解决方案1】:

GtkMenu 可以分配给 Glade 中的 GtkMenuToolButton,菜单内容也可以


填充 GtkMenu

在您的 Glade 项目中添加了 GtkMenu 后,在侧边栏中选择它,您应该会看到一个额外的工具栏图标出现:

这将打开菜单编辑器:

从这里您可以切换到“层次结构”选项卡,您可以在其中使用 + / - 按钮从菜单中添加删除项目


将 GtkMenu 分配给 GtkMentToolButton

现在不幸的是 Glade 不支持这样做,但是底层 GtkBuilder 文件格式支持as explained in the docs

GtkMenuToolButton 作为 GtkBuildable

GtkBuildable 接口的 GtkMenuToolButton 实现支持通过将“menu”指定为元素的“type”属性来添加菜单。

带有菜单的 UI 定义片段示例:

<object class="GtkMenuToolButton">
    <child type="menu">
        <object class="GtkMenu"/>
    </child>
</object>

所以点击保存(并退出)并切换到像 Gedit 这样的文本编辑器,我希望你的文件看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow">
    <property name="can_focus">False</property>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkToolbar">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkMenuToolButton" id="toolbutton">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">Menu</property>
                <property name="use_underline">True</property>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="homogeneous">True</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </object>
    </child>
  </object>
  <object class="GtkMenu" id="menu">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <child>
      <object class="GtkMenuItem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Yes</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">You Can</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">Define Menus</property>
        <property name="use_underline">True</property>
      </object>
    </child>
    <child>
      <object class="GtkMenuItem">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <property name="label" translatable="yes">In Glade</property>
        <property name="use_underline">True</property>
      </object>
    </child>
  </object>
</interface>

现在在GtkMenuToolButton 中创建一个&lt;child type="menu"&gt;,如下所示:

<object class="GtkMenuToolButton" id="toolbutton">
    <property name="visible">True</property>
    <property name="can_focus">False</property>
    <property name="label" translatable="yes">Menu</property>
    <property name="use_underline">True</property>
    <child type="menu">
    </child>
</object>

然后在 &lt;child type="menu"&gt; 中剪切并粘贴 GtkMenu 定义,不用担心缩进 Glade 会在接下来解决这个问题。

文件现在应该如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.20.0 -->
<interface>
    <requires lib="gtk+" version="3.20"/>
    <object class="GtkWindow">
        <property name="can_focus">False</property>
        <child>
            <object class="GtkBox">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                    <object class="GtkToolbar">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                        <object class="GtkMenuToolButton" id="toolbutton">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="label" translatable="yes">Menu</property>
                            <property name="use_underline">True</property>
                            <child type="menu">
                                <object class="GtkMenu" id="menu">
                                    <property name="visible">True</property>
                                    <property name="can_focus">False</property>
                                    <child>
                                        <object class="GtkMenuItem">
                                            <property name="visible">True</property>
                                            <property name="can_focus">False</property>
                                            <property name="label" translatable="yes">Yes</property>
                                            <property name="use_underline">True</property>
                                        </object>
                                    </child>
                                    <child>
                                        <object class="GtkMenuItem">
                                            <property name="visible">True</property>
                                            <property name="can_focus">False</property>
                                            <property name="label" translatable="yes">You Can</property>
                                            <property name="use_underline">True</property>
                                        </object>
                                    </child>
                                    <child>
                                        <object class="GtkMenuItem">
                                            <property name="visible">True</property>
                                            <property name="can_focus">False</property>
                                            <property name="label" translatable="yes">Define Menus</property>
                                            <property name="use_underline">True</property>
                                        </object>
                                    </child>
                                    <child>
                                        <object class="GtkMenuItem">
                                            <property name="visible">True</property>
                                            <property name="can_focus">False</property>
                                            <property name="label" translatable="yes">In Glade</property>
                                            <property name="use_underline">True</property>
                                        </object>
                                    </child>
                                </object>
                            </child>
                        </object>
                        <packing>
                            <property name="expand">False</property>
                            <property name="homogeneous">True</property>
                        </packing>
                    </child>
                </object>
                <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                </packing>
                </child>
                <child>
                    <placeholder/>
                </child>
            </object>
        </child>
    </object>
</interface>

现在保存并关闭文件,然后在 Glade 中再次打开它。

您现在应该看到 glade 将其识别为“菜单子项”,点击保存,Glade 也会为您解决缩进问题

在 Windows 10 上使用 Glade 3.20.0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-28
    • 2020-01-11
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    相关资源
    最近更新 更多