Search code examples
pythonpython-3.xpyqtpyqt4

PyQt4: icons not displayed in QMenu


I've written the following PyQt4 snippet:

#!/usr/bin/env python3

import sys
from typing import Callable, Optional

from PyQt4 import QtCore, QtGui


class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self._createMenuBar()

    def _createMenuBar(self):
        mainMenu = self.menuBar()

        fileMenu = mainMenu.addMenu("File")
        fileMenu.addAction(self._createFileNewAction())

    def _createFileNewAction(self) -> QtGui.QAction:
        return self._createAction(
            self.style().standardIcon(QtGui.QStyle.SP_DialogSaveButton),
            "New",
            QtGui.QKeySequence.New,
            "Load new image to be annotated",
            self._fileNew
        )

    def _createAction(
            self,
            icon: Optional[QtGui.QIcon],
            name: str,
            shortcut: Optional[QtGui.QKeySequence],
            tooltip: Optional[str],
            callback: Callable[[], None]
        ) -> QtGui.QAction:

        if icon is not None:
            action = QtGui.QAction(icon, name, self)
        else:
            action = QtGui.QAction(name, self)

        if shortcut is not None:
            action.setShortcut(shortcut)

        action.setToolTip(tooltip)
        action.setToolTip(tooltip)

        self.connect(action, QtCore.SIGNAL('triggered()'), callback)

        return action   

    def _fileNew(self):
        pass


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    mainWin = MainWindow()
    mainWin.show()

    app.exec_()

When I execute this program, I would expect the SP_DialogSaveButton icon to be displayed next to the "New" field in the "File" drop-down menu but it is not. PyQt is definitely able to find the icon itself, I have tried obtaining it the same way as above and displaying it in a separate QLabel which works fine.

Can someone tell what is going on here?


Solution

  • The problem is not standardIcon, if you use any icon you will observe the same behavior.

    In Qt4 the icons of the QActions are hidden in menus, to make them visible there are 2 possibilities:

    • Disable the Qt::AA_DontShowIconsInMenus attribute:

      if __name__ == '__main__':
          app = QtGui.QApplication(sys.argv)
          app.setAttribute(QtCore.Qt.AA_DontShowIconsInMenus, False)
          mainWin = MainWindow()
          mainWin.show()
          sys.exit(app.exec_())
      
    • Use the setIconVisibleInMenu() method of QAction:

      action = QtGui.QAction(icon, name, self)
      action.setIconVisibleInMenu(True)