Icons in popup menus as of 2024


I’ve spent some time now searching how to force showing an icon in my popup menu. Unfortunately none of the hints from the last decade and a half (basically since Gtk3 came) actually worked. The problem can be seen in the wxPython demo’s Menu sample.

My environment is an Ubuntu 22.04 LTS install using the default GNOME-based Ubuntu desktop. Using the system installation of wxPython 4.2.1 and wxGtk 3.2.2 with Gtk 3.24.38.

There is a gsettings entry com.canonical.unity.desktop.interface menus-have-icons, but enabling it doesn’t change anything. Neither did setting gtk-menu-images = 1 in .config/gtk-3.0/settings.ini. For my own app, I called SetBitmap() for sure, but also the wxPython demo is missing the icons.

So is there any way to get wxPython menu icons back in this modern world of today?

Thanks in advance for any pointers.

When I run the PopupMenu example in the wxPython Demo, the popup menu does show the smiley bitmap next to item ‘One’.

I am running wxPython 4.2.1 + Python 3.10.12 + Linux Mint 21.3, and am using the Mate desktop environment.


What version of wxGtk and Gtk?

Gtk is version 3.24.33

>>> wx.version()
'4.2.1 gtk3 (phoenix) wxWidgets'

How are you getting the version of wxGtk?

Well the wxGtk version is the wxWidgets version I suppose. What I wrote was based on the installed package versions in Ubuntu.

Just tried on a Raspberry Pi 4 on Bookworm (Wayland, MATE if I’m not mistaken), which has wxPython 4.2.0. No menu icons either in the demo.

My Mint-MATE installation has an app which can be run from: Menu -> Preferences -> Desktop Settings

On the ‘Interface’ tab, there is an option ‘Show icons on menus’. If I switch that option off, then the smiley doesn’t appear in the demo’s popup menu. If I switch it on, the smiley does appear.

Does your desktop environment have an equivalent setting?

On GNOME there isn’t (on my dev laptop).

The Raspberry Pi desktop is LXDE-based and I haven’t found a matching setting there. There is an option in gsettings org.mate.desktop.interface menus-have-icons though, that’s why I thought it was a Mate desktop. It obviously doesn’t work either, though.

UPDATE: It now works for the Raspberry Pi OS desktop. There’s apparently no menu entry for the tool, but the lxappearance utility has an option for this.

Still need a solution for the GNOME desktop.

In the thread Menu icons don't show up on Ubuntu, do on others @Robin suggests the Gnome Tweak Tools may have an option.

Checked that, it doesn’t unfortunately. What’s strange is that the similar gsettings key org.gnome.desktop.interface menus-have-icons has vanished as well, that must have existed at some point. And the package description of gnome-tweaks does mention the possibility to configure “icons in menus and buttons”, but the actual UI does not show such an option. I guess it has been removed from Gtk for good at some point…

EDIT: Found a screenshot of the setting in GNOME Tweaks (formerly known as Tweak Tool):

Are icons on FlatMenus visible on Gnome?

import wx
import wx.lib.agw.flatmenu as FM

class MyFrame(wx.Frame):
    def __init__(self, parent):
        super().__init__(parent, title="Right-click for popup menu")
        panel = wx.Panel(self)
        self.Bind(wx.EVT_CONTEXT_MENU, self.OnPopupMenu)

    def OnPopupMenu(self, event):
        pos = event.GetPosition()
        popup_menu = FM.FlatMenu()
        bmp = wx.ArtProvider.GetBitmap(wx.ART_CUT, wx.ART_MENU, (16, 16))
        item = FM.FlatMenuItem(popup_menu, -1, "Cut", normalBmp=bmp)
        bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_MENU, (16, 16))
        item = FM.FlatMenuItem(popup_menu, -1, "Copy", normalBmp=bmp)
        bmp = wx.ArtProvider.GetBitmap(wx.ART_PASTE, wx.ART_MENU, (16, 16))
        item = FM.FlatMenuItem(popup_menu, -1, "Paste", normalBmp=bmp)

if __name__ == '__main__':
    app = wx.App()
    frame = MyFrame(None)

Right-click for popup menu_001

Yes the FlatMenu does show icons on this machine. I’ll see whether it’s a possibility to switch. Might not be so easy because the GUI is generated using wxFormBuilder and I think it doesn’t have a FlatMenu in its controls gallery.

I use wxGlade rather wxFormBuilder. The former has an option for adding ‘custom widgets’ to a project. I use this when adding controls such as RichTextCtrl or StyledTextCtrl which don’t appear in the palette. The downside is that wxGlade shows a place-marker instead of the actual control. However, the real control is generated in the output.

Does wxFormBuilder have an equivalent option?

Yes, it allows to set a “subclass” attribute (with associated “header” for importing the needed module) on pretty much any control. This way one can use an own implementation derived from the placed standard control class. That derived control cannot be based on some structure defined in the same wxFormBuilder output though, as that would cause an import cycle. Still pretty useful for placing customized controls.

The other possibility is a CustomControl object, but I haven’t experimented with that yet. Especially whether it works with wxPython. Could just as well be useful for importing a FlatMenu though. Good idea, I’ll try that next…