wxPython菜单不显示图像
我正在创建一个菜单,并给菜单项分配图片。有时候,菜单中的第一个项目不显示任何图片,我找不到原因。我尝试做了一个简单的独立示例,下面的代码在我的电脑上展示了这个问题。我使用的是Windows XP,wx 2.8.7.1(msw-unicode)。
import wx
def getBmp():
bmp = wx.EmptyBitmap(16,16)
return bmp
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, style=wx.DEFAULT_FRAME_STYLE, parent=None)
self.SetTitle("why New has no image?")
menuBar = wx.MenuBar()
fileMenu=wx.Menu()
item = fileMenu.Append(wx.ID_NEW, "New")
item.SetBitmap(getBmp())
item = fileMenu.Append(wx.ID_OPEN, "Open")
item.SetBitmap(getBmp())
item = fileMenu.Append(wx.ID_SAVE, "Save")
item.SetBitmap(getBmp())
menuBar.Append(fileMenu, "File")
self.SetMenuBar(menuBar)
app = wx.PySimpleApp()
frame=MyFrame()
frame.Show()
app.SetTopWindow(frame)
app.MainLoop()
你能看到这个问题吗?可能是什么原因呢?
结论:是的,这是一个官方的bug。我创建了一个简单的菜单类来解决这个bug,使用了“balpha”在选定答案中给出的技巧。
这个类重写了每个菜单的Append方法,并检查是否是第一次添加带图片的菜单项。如果是,就创建一个虚拟项,之后再删除它。
这还增加了一个功能/限制,即在调用SetBitmap时,你应该把图片作为可选参数传入。
import wx
class MockMenu(wx.Menu):
"""
A custom menu class in which image param can be passed to each Append method
it also takes care of bug http://trac.wxwidgets.org/ticket/4011
"""
def __init__(self, *args, **kwargs):
wx.Menu.__init__(self, *args, **kwargs)
self._count = 0
def applyBmp(self, unboundMethod, *args, **kwargs):
"""
there is a bug in wxPython so that it will not display first item bitmap
http://trac.wxwidgets.org/ticket/4011
so we keep track and add a dummy before it and delete it after words
may not work if menu has only one item
"""
bmp = None
if 'image' in kwargs:
bmp = kwargs['image']
tempitem = None
# add temp item so it is first item with bmp
if bmp and self._count == 1:
tempitem = wx.Menu.Append(self, -1,"HACK")
tempitem.SetBitmap(bmp)
ret = unboundMethod(self, *args, **kwargs)
if bmp:
ret.SetBitmap(bmp)
# delete temp item
if tempitem is not None:
self.Remove(tempitem.GetId())
self._lastRet = ret
return ret
def Append(self, *args, **kwargs):
return self.applyBmp(wx.Menu.Append, *args, **kwargs)
def AppendCheckItem(self, *args, **kwargs):
return self.applyBmp(wx.Menu.AppendCheckItem, *args, **kwargs)
def AppendMenu(self, *args, **kwargs):
return self.applyBmp(wx.Menu.AppendMenu, *args, **kwargs)
2 个回答
4
如果你用 wx.MenuItem() 创建每个菜单项,先设置它的图标,然后再把它添加到菜单里,这个小技巧就不需要了。这样做可以让图标正确显示。我是在 Windows 上用 wxPython 2.8.10.1 测试的。
2
这是一个确认存在的bug,看起来已经存在了一段时间。经过一些尝试,这个解决方法似乎有效:
menuBar = wx.MenuBar()
fileMenu=wx.Menu()
tempitem = fileMenu.Append(-1,"X") # !!!
tempitem.SetBitmap(getBmp()) # !!!
item = fileMenu.Append(wx.ID_NEW, "New")
fileMenu.Remove(tempitem.GetId()) # !!!
item.SetBitmap(getBmp())
item = fileMenu.Append(wx.ID_OPEN, "Open")
item.SetBitmap(getBmp())
item = fileMenu.Append(wx.ID_SAVE, "Save")
item.SetBitmap(getBmp())
menuBar.Append(fileMenu, "File")
self.SetMenuBar(menuBar)
请注意,fileMenu.Remove调用的位置是最早可以正常工作的地方,但你也可以把它移动到最后。希望这对你有帮助。