2009-07-03 14 views
3

Je crée un menu et j'attribue des images à des éléments de menu, parfois le premier élément du menu n'affiche aucune image, je n'arrive pas à trouver la raison. J'ai essayé de faire un exemple autonome simple et ci-dessous est le code qui démontre le problème sur ma machine. J'utilise Windows XP, WX 2.8.7.1 (MSW-unicode) »Le menu wxPython n'affiche pas l'image

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

Alors êtes-vous en mesure de voir le problème et ce qui pourrait être la raison?

Conclusion: Oui cela est un bug officiel, j'ai créé une simple classe Menu pour résoudre ce bogue, en utilisant l'astuce donnée par « balpha » en réponse choisie

Il remplace chaque méthode et menu.Append voit si l'élément de menu avec l'image est ajouté pour la première fois, si oui crée un élément fictif et le supprime plus tard.

Cela ajoute également fonction/contrainte de sorte qu'au lieu d'appeler SetBitmap, vous devez passer bitmap comme image argument optionnel

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) 

Répondre

2

C'est un confirmed bug qui a appearently été ouverte pendant un certain temps. Après avoir essayé un petit peu, cette solution de contournement semble le faire:

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) 

Notez que la position de l'appel fileMenu.Remove est la première position qui fonctionne, mais vous pouvez aussi le déplacer vers le bas. HTH.

+0

Merci, cela fonctionne et en utilisant cela, j'ai ajouté une classe MockMenu pour mon but et ajouté pour répondre aussi. –

4

Ce hack ne semble pas nécessaire si vous créez chaque élément de menu avec wx.MenuItem(), définissez son bitmap, puis seulement l'ajouter au menu. Cela provoque l'affichage correct des bitmaps. Je suis en train de tester avec wxPython 2.8.10.1 sous Windows.

Questions connexes