【问题标题】:wxPython menu doesn't display imagewxPython 菜单不显示图像
【发布时间】:2010-11-07 21:32:59
【问题描述】:

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

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)

【问题讨论】:

    标签: python menu wxpython


    【解决方案1】:

    如果您使用 wx.MenuItem() 创建每个菜单项,设置其位图,然后才将其附加到菜单,则此 hack 似乎没有必要。这会导致位图正确显示。我正在 Windows 上使用 wxPython 2.8.10.1 进行测试。

    【讨论】:

      【解决方案2】:

      这是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。

      【讨论】:

      • 谢谢,它确实有效,我为此添加了一个 MockMenu 类并添加了答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-26
      • 1970-01-01
      相关资源
      最近更新 更多