【问题标题】:MenuItem bitmaps raises an assert failure …MenuItem 位图引发断言失败……
【发布时间】:2017-12-09 04:00:06
【问题描述】:

我正在尝试在Preferences 菜单项前面有一个漂亮的齿轮位图。这就是我认为应该编码的方式:

    menubar = wx.MenuBar()
    fileMenu = wx.Menu()
    preferences = wx.MenuItem(text="Preferences",
                              helpString="Opens preferences dialog.",
                              kind=wx.ITEM_NORMAL)
    gear = wx.Bitmap(os.path.join(os.path.dirname(__file__), 'gear.png'))
    preferences.SetBitmap(gear)
    self.shcfg = fileMenu.Append(preferences)

但是,这是错误的,因为我得到了一个

Traceback (most recent call last):                                              
  File "gui.py", line 193, in <module>                                          
    GUI(None)                                                                   
  File "gui.py", line 117, in __init__                                          
    self.InitUI()                                                               
  File "gui.py", line 129, in InitUI                                            
    preferences.SetBitmap(gear)                                                 
wx._core.wxAssertionError: C++ assertion "Assert failure" failed at /tmp/pip-build-sc_vd1aj/wxPython/ext/wxWidgets/src/gtk/menu.cpp(729) in SetBitmap(): only normal menu items can have bitmaps 

我做错了什么?

【问题讨论】:

    标签: linux windows python-3.x wxpython wxwidgets


    【解决方案1】:

    您使用的是Append 而不是AppendItem

    我想有很多方法可以将菜单放在一起,但我发现所有菜单项都需要一个 ID。
    对于预定义的 wx id,它很简单,因为您可以简单地附加它们,因为它们不仅带有内置 ID,还带有图像。
    对于自定义图像,我使用以下方法,该方法一直对我有用。
    请注意,我在此示例代码中同时使用了预定义的 Id 和自定义 Id。
    我在下面包含了您的代码的变体

    #!/usr/bin/python
    # -*- coding: utf-8 -*-
    import wx
    import os
    class MainWindow(wx.Frame):
        def __init__(self, parent, title):
            wx.Frame.__init__(self, parent, title=title, size=(200, 100))
            self.control = wx.TextCtrl(self, style=wx.TE_MULTILINE)
    
            # Create Statusbar
            self.CreateStatusBar()
    
            # Set up the menus
            filemenu = wx.Menu()
            infomenu = wx.Menu()
    
            # file menu
            filemenu.Append(wx.ID_NEW, "New") # Id of wx.ID_NEW (5002) which picks up an automatic image
            filemenu.Append(wx.ID_SAVE, "Save")
    
            m1 = wx.MenuItem(filemenu, 100, "Manual Bitmap") #A manual id of 100
            m1.SetBitmap(wx.Bitmap('./myimage1.png'))
            filemenu.AppendItem(m1)
    
            m2 = wx.MenuItem(filemenu, 101, "Manual Bitmap 2") #A manual id of 101
            m2.SetBitmap(wx.Bitmap('./myimage2.png'))
            filemenu.AppendItem(m2)
            #----------------------------------------------#    
            preferences = wx.MenuItem()
            preferences.SetId(102)
            preferences.SetText("Preferences")
            preferences.SetHelp("Preferences Help")
            preferences.SetKind(wx.ITEM_NORMAL)
            gear = wx.Bitmap(os.path.join(os.path.dirname(__file__), 'myimage2.png'))
            preferences.SetBitmap(gear)
            filemenu.AppendItem(preferences)
            #----------------------------------------------#    
            filemenu.AppendSeparator()
    
            filemenu.Append(wx.ID_EXIT, "Exit")
    
            # info menu
            infomenu.Append(wx.ID_ABOUT, "About")
    
            # bind file menu
            self.Bind(wx.EVT_MENU, self.OnManualBitmap, id=100) # Bind to the Id
            self.Bind(wx.EVT_MENU, self.OnManualBitmap, id=101) # Bind to the Id
            self.Bind(wx.EVT_MENU, self.OnManualBitmap, id=102) # Bind to the Id
            self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
    
            # Creating the menubar.
            menuBar = wx.MenuBar()
    
            # Add menus
            menuBar.Append(filemenu, "&Preferences")
            menuBar.Append(infomenu, "&Help")
    
            # Add the MenuBar to the Frame content.
            self.SetMenuBar(menuBar)
            self.Show(True)
    
        def OnManualBitmap(self, event):
            print event.EventObject.GetLabel(event.Id)
            print event.Id
    
        def OnExit(self, event):
            self.Destroy()
    
    app = wx.App()
    frame = MainWindow(None, "Menu Image Test")
    app.MainLoop()
    

    【讨论】:

    • Raises AttributeError: 'MenuItem' object has no attribute 'SetId'... 我正在运行 Python 3,而不是 2。破解代码以便编译会引发与问题中相同的错误。 ☹
    • 你不能用 python3 运行 wxpython(经典)。如果您正在运行 wxpython phoenix,据我所知,它还没有!我的答案使用 wxpython 3.0.2.0 gtk2 (classic) 和 Python 2.7.12 运行愉快,我想这一切都在版本中;)
    • 我正在运行 wxpython phoenix。所以我想我不能那样做。不用担心。
    • 您可以绑定到 menuitem 名称而不是 id,因此在这种情况下 preferences 但使用 wx classic 在我的测试中 id 返回 -2 用于绑定的所有项目这样一来,不尽如人意。 Phoenix 可能会有所不同,尽管我仍然无法找到它的文档,并且我想,在某个时候,我将不得不将大量共享软件项目迁移到 wx phoenix。
    • Phoenix 仍处于 alpha/beta 阶段,所以我现在不会太努力。它处于不断变化的状态。
    【解决方案2】:

    您是否尝试过省略kind=wx.ITEM_NORMAL?看起来它可能被 wxPython 错误处理并导致创建一个可检查的项目。至少,根据断言消息,这就是以某种方式最终发生的事情。

    【讨论】:

      猜你喜欢
      • 2011-07-07
      • 2011-05-27
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2022-06-13
      • 1970-01-01
      相关资源
      最近更新 更多