问题 QIcon.fromTheme不在PyQt中显示图标


我在显示从当前图标主题中选择的QAction的图标时遇到麻烦。我用Qt设计师制作了ui并将其导出 pyuic4 sample.ui > sample.py。从主题设置图标后 self.actionSample.setIcon(QtGui.QIcon.fromTheme(_fromUtf8("document-open"))),我得到以下源代码:

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_()

当我执行它时,工具栏不会显示图标'document-open'。这是一个错误还是我做错了什么?

谢谢


8428
2017-10-09 17:13


起源

你在玩什么平台,你使用的是什么版本的Qt?此外,您是否在Designer中设置了图标,或者手动添加它? - ekhumoro
@ekhumoro我正在运行:Gnu / Linux 3.2.0-2-686 - Debian Testing / Python 2.7.3rc2 / python-qt4 4.9.3-4 /我在生成图标后手动设置图标 .py文件。但是当我用qt-designer生成它时它是一样的。 - Hypergraphe
操作编辑器中的“新建操作”对话框应显示“图标主题”属性旁边的图标(如果可用)。 - ekhumoro
当我打开动作编辑器时,我在“图标主题”文本编辑中编写了“文档打开”。但我没有看到任何图标。 - Hypergraphe


答案:


使用的图标查找过程 QIcon.fromTheme 有点复杂。

对于GNOME和KDE桌面环境,仅在X11平台上直接支持图标主题。对于其他平台/桌面,有必要与应用程序一起安装主题,或以各种方式调整用户的环境。

要查找GNOME的当前系统主题,Qt将查询gconf(如果gtk样式可用),否则默认为“gnome”主题。对于KDE,Qt将检查 kdeglobals 设置文件,否则默认为“氧气”(或早期版本的KDE的“crystalsvg”)。此外,“hicolor”主题始终可以用作后备。

一旦确定了系统主题名称,Qt将在各种预定位置查找包含图标的目录,这又取决于所使用的平台和桌面。在X11上,这包括 $HOME/.icons 和 $XDG_DATA_DIRS/icons。所有平台/桌面共有的唯一位置是资源路径 :/icons

图标主题目录必须包含 index.theme 文件,其中(除其他外)指定可以包含图标的子目录。只有图标文件 png 要么 svg 使用扩展名。

QIcon class有一些静态方法,可以准确显示Qt在哪里寻找主题图标:

>>> 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

如果没有显示“文档打开”图标,Qt要么在“错误”的位置查看,要么图标完全丢失。

更新:

如上所述:默认情况下,Qt仅在X11平台上支持GNOME和KDE。它对FluxBox WM一无所知,因此无法检测当前的图标主题。这意味着它将回归到使用最小的“hicolor”主题,这可能没有所有必需的图标。

解决此问题的一种方法是创建一个指向您要使用的主题的“hicolor”符号链接。理想情况下,这应该位于Qt搜索路径列表中的第一个位置:

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

更新2

Qt5默认只支持kde和gnome,但是 Qt平台抽象层 至少可以创建自定义主题插件(LXQT 是一个利用这个的桌面环境)。还有几个DE现在被视为gtk / gnome:X-CINNAMON,UNITY,MATE,XFCE和LXDE。


11
2017-10-10 18:21



我正在运行FluxBox WM。当我执行上面的代码片段时,我得到: /home/ben/.icons/hicolor /usr/local/share/icons/hicolor /usr/share/icons/hicolor :/icons/hicolor   图标位于 /usr/share/icons/hicolor 以及index.theme所以它应该正常工作? - Hypergraphe
好的,我改变了主题 setThemeName 我的一个静态方法 .icons 它运作良好。任何想法为什么PyQt不会调查其他搜索路径? - Hypergraphe
那是个好主意。我去做。非常感谢你。 - Hypergraphe