Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QIcon.fromTheme not displaying icon in PyQt

I am having troubles to display the icon of a QAction selected from the current icon theme. I made the ui with Qt designer and exported it with pyuic4 sample.ui > sample.py. After setting the icon from the theme with self.actionSample.setIcon(QtGui.QIcon.fromTheme(_fromUtf8("document-open"))), I get the following source code :

from PyQt4 import QtCore, QtGui
import sys

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.toolBar = QtGui.QToolBar(MainWindow)
        self.toolBar.setObjectName(_fromUtf8("toolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.actionSample = QtGui.QAction(MainWindow)
        self.actionSample.setObjectName(_fromUtf8("actionSample"))
        self.actionSample.setIcon(QtGui.QIcon.fromTheme(_fromUtf8("document-open")))
        self.toolBar.addAction(self.actionSample)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(window)
    window.show()
    app.exec_()

When I execute it, the toolbar does not display the icon 'document-open'. Is it a bug or am I doing something wrong ?

Thanks

like image 783
Hypergraphe Avatar asked Oct 09 '12 17:10

Hypergraphe


People also ask

How to set icon to a window in PyQt5?

How to set icon to a window in PyQt5 ? When we design a PyQt5 application we see an icon on the top left corner, by default it looks like this : In this tutorial, we will see how to change the icon according to the user need, in order to do this we use setWindowIcon () method and to load the icon QIcon will be used which belongs to QtGui class.

Can I use qicon with an icon theme?

The icon lookup process used by QIcon.fromTheme is somewhat complex. Icon themes are only directly supported on the X11 platform for the GNOME and KDE desktop environments. For other platforms/desktops, it will be necessary to either install a theme along with the application, or tweak the user's environment in various ways.

What is qicon in Qt?

A QIcon can generate smaller, larger, active, and disabled pixmaps from the set of pixmaps it is given. Such pixmaps are used by Qt widgets to show an icon representing a particular action. The simplest use of QIcon is to create one from a QPixmap file or resource, and then use it, allowing Qt to work out all the required icon styles and sizes.

How do I know where the qicon is looking for icons?

Only icon files with a png or svg extension are used. The QIcon class has some static methods which will show exactly where Qt is looking for themed icons: If the "document-open" icon isn't being displayed, Qt is either looking in the "wrong" place, or the icon is missing altogether.


1 Answers

The icon lookup process used by QIcon.fromTheme is somewhat complex.

Icon themes are only directly supported on the X11 platform for the GNOME and KDE desktop environments. For other platforms/desktops, it will be necessary to either install a theme along with the application, or tweak the user's environment in various ways.

To find the current system theme for GNOME, Qt will query gconf (if the gtk style is available), and otherwise default to the "gnome" theme. For KDE, Qt will examine the kdeglobals settings file(s), and otherwise default to "oxygen" (or "crystalsvg" for earlier versions of KDE). In addition, the "hicolor" theme can always be used as a fallback.

Once the system theme name has been determined, Qt will look for the directory containing the icons in various pre-determined places, which again depend on both the platform and desktop being used. On X11, this includes $HOME/.icons and $XDG_DATA_DIRS/icons. The only location common to all platforms/desktops is the resource path :/icons.

Icon theme directories must include an index.theme file, which (amongst other things) specifies the subdirectories that can contain icons. Only icon files with a png or svg extension are used.

The QIcon class has some static methods which will show exactly where Qt is looking for themed icons:

>>> from PyQt4 import QtGui
>>> app = QtGui.QApplication([])
>>> for path in QtGui.QIcon.themeSearchPaths():
...     print "%s/%s" % (path, QtGui.QIcon.themeName())
... 
/home/ekhumoro/.icons/hicolor
/usr/local/share/icons/hicolor
/usr/share/icons/hicolor
:/icons/hicolor

If the "document-open" icon isn't being displayed, Qt is either looking in the "wrong" place, or the icon is missing altogether.

UPDATE:

As I said above: by default, Qt only supports GNOME and KDE on the X11 platform. It doesn't know anything about FluxBox WM, and so cannot detect the current icon theme. This means it will fall back to using a minimal "hicolor" theme, which may not have all the required icons.

One way to solve this issue, is to create a "hicolor" symlink that points to the theme you want to use. Ideally, this should go in the location that is first in Qt's list of search paths:

$ ln -s icon/theme/directory $HOME/.icons/hicolor

UPDATE 2:

Qt5 still only supports kde and gnome by default, but the Qt Platform Abstraction layer at least makes it possible to create custom theme plugins (LXQT is one desktop environment that takes advantage of this). There are also several more DE's that are now treated as gtk/gnome: X-CINNAMON, UNITY, MATE, XFCE and LXDE.

like image 171
ekhumoro Avatar answered Sep 18 '22 11:09

ekhumoro