代码之家  ›  专栏  ›  技术社区  ›  Anurag Uniyal

wxpython菜单不显示图像

  •  3
  • Anurag Uniyal  · 技术社区  · 15 年前

    我正在创建一个菜单并为菜单项分配图像,有时菜单中的第一项不显示任何图像,我找不到原因。我试着做一个简单的独立的例子,下面的代码在我的机器上演示了这个问题。 我使用的是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()
    

    那么你能看到问题所在吗?原因是什么?

    结论 :是的,这是一个官方错误,我创建了一个简单的菜单类来克服这个错误,使用“balpha”在所选答案中给出的技巧。

    它重写每个menu.append方法,并查看是否第一次添加带有图像的菜单项,如果是,则创建一个虚拟项,稍后将其删除。

    这还添加了功能/约束,这样就不必调用setbitmap,而是应该将bitmap作为可选参数image传递。

    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 回复  |  直到 15 年前
        1
  •  2
  •   balpha    15 年前

    这是一个 confirmed 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调用的位置是最早可用的位置,但也可以将其移到底部。Hth.

        2
  •  4
  •   da    15 年前

    如果使用wx.menuItem()创建每个菜单项,设置其位图,然后将其附加到菜单中,则似乎不需要进行此黑客操作。这会导致位图正确显示。我正在Windows上使用Wxpython 2.8.10.1进行测试。