2015-08-15 307 views
0

我想在我的Python应用程序中创建一个Gtk.MenuBar。 This就是我用作教程的东西。以下是我创建的菜单栏代码:什么原因导致'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) 

然而,当我尝试实例化,并添加到我的主窗口中,我得到了以下断言失败:

(__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,所以我不知道发生了什么。

我在犯什么错误?

编辑#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 

和呼叫用于创建应用程序本身:插入正确的

__author__ = 'xiaolong' 

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

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文件我创建目录结构,这些文件应该是一个工作的例子。我已经设置了目录如下:由于出现在XLDMenuBar.py行self.add(vertical_box)你在哪里尝试添加Gtk.Box(不是菜单项)的菜单栏的

gtkplustool --> __main__.py 
gtkplustool --> GTKSignal.py 
gtkplustool --> gui --> XLDMainWindow.py 
gtkplustool --> gui --> XLDMenuBar.py 
+0

你能提供一个*工作*例?包括您正在使用的最小窗口。 – elya5

+0

我会尽力的。编辑问题。 – Zelphir

回答

2

错误。

得到它的工作,你可以简单地删除此行与上述三个并修改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) 
相关问题