2009-07-03 67 views
3

我正在創建菜單並將圖像分配給菜單項,有時菜單中的第一項不顯示任何圖像,我無法找到原因。我試圖做一個簡單的獨立示例,下面是在我的機器上演示問題的代碼。 我使用Windows XP,WX 2.8.7.1(MSW-Unicode)的」wxPython菜單不顯示圖像

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() 

所以你能看到問題,可能是什麼原因呢?

結論:是的,這是一個官方的錯誤,我創建了一個簡單的菜單類來克服這一缺陷,使用選擇的答案是「balpha」給出的伎倆

它覆蓋每個menu.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

這是一個confirmed bug這appearently已經開了一段時間了。周圍的一點點努力之後,這個解決辦法似乎做到這一點:

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呼叫的立場是,工作最早的位置,但你也可以把它移到底部。 HTH。

+0

謝謝,它確實工作,並使用此我添加了一個MockMenu類爲我的目的,並添加到回答。 – 2009-07-03 11:26:52

4

如果你用wx.MenuItem()創建每個菜單項,設置它的位圖,然後將它附加到菜單中,這種破解似乎不是必須的。這會導致位圖正確顯示。我在Windows上使用wxPython 2.8.10.1進行測試。