MenuItem 位图引发断言失败……

MenuItem bitmaps raises an assert failure …

我正在尝试在 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 

我做错了什么?

您使用的是 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()

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