是什么原因导致断言“GTK_IS_MENU_ITEM(child)”失败?

2021-03-01 03:36:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创造一个Gtk菜单栏在我的Python应用程序中。This是我用作教程的东西。以下是我创建菜单栏的代码:

# -*- coding: utf-8 -*-
import GTKSignal

__author__ = 'xiaolong'

from gi.repository import Gtk


class XLDMenuBar(Gtk.MenuBar):
    MENUBAR_UI_INFO = """<ui>
            <menubar name='MenuBar'>
                <menu action='FileMenu'>

                    <menu action='File_New'>
                        <menuitem action='File_New_Dictionary' />
                    </menu>

                    <separator />

                    <menuitem action='File_Open' />

                    <menuitem action='File_Save' />

                    <menu action='File_SaveAs'>
                        <menuitem action='File_SaveAs_Dictionary' />
                        <menuitem action='File_SaveAs_SearchResult' />
                        <menuitem action='File_SaveAs_SelectedVocables' />
                    </menu>

                    <menuitem action='File_Exit' />

                </menu>
            </menubar>
        </ui>"""

    def __init__(self, parent):
        super().__init__()

        self.parent = parent
        self.toplevel_menubar_action_group = Gtk.ActionGroup("toplevel_menubar_action_group")

        self.initialize_file_menu()
        self.add_file_menu()
        self.add_menu_action_handlers()

        # TODO: add other actions, so far only file menu

        self.load_ui_info()

    def initialize_file_menu(self):
        self.action_filemenu = Gtk.Action(name='FileMenu', label='File', tooltip='opens the file menu', stock_id=None)

        # file -> new
        self.action_filemenu_new = Gtk.Action(name='File_New', label='New', tooltip=None, stock_id=None)
        self.action_filemenu_new_dictionary = Gtk.Action(
            name='File_New_Dictionary',
            label='New dictionary …',
            tooltip='opens the dialog for creating a new dictionary',
            stock_id=Gtk.STOCK_NEW
        )

        # file -> open
        self.action_filemenu_open = Gtk.Action(
            name='File_Open',
            label='Open …',
            tooltip='opens the dialog for opening files',
            stock_id=Gtk.STOCK_OPEN
        )

        # file -> save
        self.action_filemenu_save = Gtk.Action(
            name='File_Save',
            label='Save',
            tooltip='saves current changes of the dictionary to the dictionary file',
            stock_id=Gtk.STOCK_SAVE
        )

        # file -> saveas
        self.action_filemenu_saveas = Gtk.Action(name='File_SaveAs', label='Save As', tooltip=None, stock_id=None)
        self.action_filemenu_saveas_dictionary = Gtk.Action(
            name='File_SaveAs_Dictionary',
            label='Save dictionary as …',
            tooltip='saves the current dictionary with current changes to a specified file',
            stock_id=Gtk.STOCK_SAVE_AS
        )
        self.action_filemenu_saveas_searchresult = Gtk.Action(
            name='File_SaveAs_SearchResult',
            label='Save search result as …',
            tooltip='saves the current search result to a specified file',
            stock_id=Gtk.STOCK_SAVE_AS
        )
        self.action_filemenu_saveas_selectedvocables = Gtk.Action(
            name='File_SaveAs_SelectedVocables',
            label='Save selected vocables as …',
            tooltip='saves the currently selected vocables to a specified file',
            stock_id=Gtk.STOCK_SAVE_AS
        )

        # file -> exit
        self.action_filemenu_exit = Gtk.Action(
            name='File_Exit',
            label='Exit',
            tooltip='Closes the application',
            stock_id=Gtk.STOCK_QUIT
        )

    def add_file_menu(self):
        self.toplevel_menubar_action_group.add_action(self.action_filemenu)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_new)
        self.toplevel_menubar_action_group.add_action_with_accel(action=self.action_filemenu_new_dictionary, accelerator=None)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_open)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_save)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_saveas)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_saveas_dictionary)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_saveas_searchresult)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_saveas_selectedvocables)
        self.toplevel_menubar_action_group.add_action(self.action_filemenu_exit)

    def add_menu_action_handlers(self):
        self.action_filemenu_new_dictionary.connect(GTKSignal.ACTIVATE, lambda widget: print('You\'ve clicked \"New dictionary\"!'))
        self.action_filemenu_exit.connect(GTKSignal.ACTIVATE, lambda widget: print('You\'ve clicked Exit!'))
        # TODO: add other action handlers

    def load_ui_info(self):
        uimanager = self.parent.create_ui_manager()
        uimanager.insert_action_group(self.toplevel_menubar_action_group)

        menubar = uimanager.get_widget("/MenuBar")

        vertical_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        vertical_box.pack_start(child=menubar, expand=False, fill=False, padding=0)

        self.add(vertical_box)

但是,当我尝试实例化并添加到主窗口时,以下断言失败:

^{pr2}$

对我来说,这听起来像是在说,我试图将一个非MenuItem添加到Menu,但我在代码中找不到。在教程网站上的示例中,他们像我一样将Gtk.Actions添加到Gtk.ActionGroups中,但是他们的代码不会导致这个断言失败。我还检查了多次UI-XML,但没有menu添加非menuitem或非menu,所以我不知道发生了什么。在

我犯的错误在哪里?在

编辑1

为了添加一个工作示例,我将插入主应用程序窗口的代码及其调用。在

主应用程序窗口:

# -*- coding: utf-8 -*-
from gi.repository import Gtk
from gui.XLDMenuBar import XLDMenuBar

__author__ = 'xiaolong'


class XLDMainWindow(Gtk.Window):

    WINDOW_TITLE = 'Xiaolong Dictionary'
    DEFAULT_X_SIZE = 400
    DEFAULT_Y_SIZE = 300
    menubar = None

    def __init__(self):
        # super().__init__(title='Xiaolong Dictionary')
        super(XLDMainWindow, self).__init__(title=self.WINDOW_TITLE)

        self.set_default_size(self.DEFAULT_X_SIZE, self.DEFAULT_Y_SIZE)

        self.initialize_widgets()
        self.add_widgets()

    def initialize_widgets(self):
        self.menubar = XLDMenuBar(self)

    def add_widgets(self):
        self.add(self.menubar)

    def connect_signals(self):
        pass

    def create_ui_manager(self):
        uimanager = Gtk.UIManager()

        # Throws exception if something went wrong
        uimanager.add_ui_from_string(XLDMenuBar.MENUBAR_UI_INFO)

        # Add the accelerator group to the toplevel window
        accelgroup = uimanager.get_accel_group()
        self.add_accel_group(accelgroup)
        return uimanager

以及创建应用程序本身的要求:

from gi.repository import Gtk
from gtkplustool import GTKSignal
from gtkplustool.gui.XLDMainWindow import XLDMainWindow

__author__ = 'xiaolong'

if __name__ == '__main__':
    xld_main_window = XLDMainWindow()
    xld_main_window.connect(GTKSignal.DELETE, Gtk.main_quit)
    xld_main_window.show_all()
    Gtk.main()

以及我创建的GTKSignal文件:

__author__ = 'xiaolong'

DELETE = 'delete-event'
CLICKED = 'clicked'
ACTIVATE = 'activate'

插入到正确的目录结构中,这些文件应该是一个工作示例。我的目录设置如下:

gtkplustool --> __main__.py
gtkplustool --> GTKSignal.py
gtkplustool --> gui --> XLDMainWindow.py
gtkplustool --> gui --> XLDMenuBar.py
1条回答
网友
1楼 ·

出现错误是因为中的self.add(vertical_box)行XLDMenuBar.py在这里您试图添加一个Gtk.箱(不是菜单项)到菜单栏。在

要使其正常工作,只需删除这行代码和上面的三行代码,然后修改XLDMainWindow.py到以下对象(并使uimanager成为类属性):

    def add_widgets(self):
        menubar = self.uimanager.get_widget("/MenuBar")
        box = Gtk.VBox()
        box.pack_start(menubar, False, False, 0)
        self.add(box)

相关问题