Я пытаюсь создать Gtk.MenuBar в моем приложении Python. This - это то, что я использовал в качестве учебника. Ниже мой код для создания MenuBar:Что вызывает утверждение 'GTK_IS_MENU_ITEM (child)' не удалось?
# -*- 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)
Однако, когда я пытаюсь создать экземпляр и добавить к моему главному окну, я получаю следующее утверждение FAIL:
(__main__.py:12392): Gtk-CRITICAL **: gtk_menu_shell_insert: assertion 'GTK_IS_MENU_ITEM (child)' failed
для меня это звучит, как будто он говорит, что я пытаюсь добавить не MenuItem
в Menu
, но я не могу найти это в своем коде. В примере на веб-сайте учебника они добавили Gtk.Action
s в Gtk.ActionGroups
так же, как и я, но их код не вызывает этого утверждения. Я также проверил UI XML несколько раз уже и нет menu
, к которому я пытаюсь добавить не menuitem
, либо не menu
, поэтому я действительно не знаю, что происходит.
Где ошибка, которую я делаю?
EDIT # 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
Можете ли вы обеспечить * работу * пример? Включая минимальное окно, которое вы используете для него. – elya5
Я попробую. Редактирование вопроса. – Zelphir