之前一直是用PyQt5的,最近的项目由于担心开源协议的问题,开始使用PySide2,没想到在简单的图片显示上就出现了问题。
问题的表现是这样的,对于有的.jpg图片,使用PyQt5是完全可以正常显示的,但是一旦换成PySide2就不行。

由于后面内容较长,所以先说解决方法

  • 出现此问题可能是用于支持jpg的dll动态链接库没有加载成功;
  • 可以通过在代码中app = QApplication(sys.argv)后追加一行app.addLibraryPath(os.path.join(os.path.dirname(QtCore.__file__), "plugins"))手动添加动态链接库予以解决;
  • 【补充】在另一个项目中发现使用上述方法仍然无效,然后发现通过在app = QApplication(sys.argv)这一行之前添加一行QImageReader.supportedImageFormats()之后可以解决,原因不明。如有知晓原因者欢迎留言;
  • 【再补充】PySide2拜拜了你爷不伺候了,直接PySide6走你,以上问题都没有了。

给出两段示例代码。
PyQt5是没问题的:

import sys

from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel

app = QApplication(sys.argv)
pixmap = QPixmap('img/cat.jpg')
label = QLabel()
label.setPixmap(pixmap)
label.show()

app.exec_()

在这里插入图片描述
以上图片来自网络
然后使用Pyside2试下:

import sys

from PySide2.QtGui import QPixmap
from PySide2.QtWidgets import QApplication, QLabel

app = QApplication(sys.argv)
pixmap = QPixmap('img/cat.jpg')
label = QLabel()
label.setPixmap(pixmap)
label.show()

app.exec_()

在这里插入图片描述

可以看到窗口是空的。

我的问题排查过程如下:

  • 首先,我去读了一下Qt的文档(我一般看C++ Qt的文档,比较详细些,API都差不多),我调用的pixmap = QPixmap('img/cat.jpg')这个方法,对应的文档地址是https://doc.qt.io/qt-5/qpixmap.html#QPixmap-2:
    在这里插入图片描述
    从文档可知,该方法的第二个参数就是图片格式。关于Qt支持的格式的详细信息,在图中红框的链接处。
  • 我点进去,文档内容如下:
    在这里插入图片描述

文档中支持的图片格式是有jpg的,但是为啥我无法显示jpg呢?

  • 我看到文档中说可以通过QImageReader::supportedImageFormats()查看,于是我就在上面的代码中加上一行print(QImageReader.supportedImageFormats()),对于PyQt5的那段代码,输出结果是:
    [PyQt5.QtCore.QByteArray(b'bmp'), PyQt5.QtCore.QByteArray(b'cur'), PyQt5.QtCore.QByteArray(b'gif'), PyQt5.QtCore.QByteArray(b'icns'), PyQt5.QtCore.QByteArray(b'ico'), PyQt5.QtCore.QByteArray(b'jpeg'), PyQt5.QtCore.QByteArray(b'jpg'), PyQt5.QtCore.QByteArray(b'pbm'), PyQt5.QtCore.QByteArray(b'pgm'), PyQt5.QtCore.QByteArray(b'png'), PyQt5.QtCore.QByteArray(b'ppm'), PyQt5.QtCore.QByteArray(b'svg'), PyQt5.QtCore.QByteArray(b'svgz'), PyQt5.QtCore.QByteArray(b'tga'), PyQt5.QtCore.QByteArray(b'tif'), PyQt5.QtCore.QByteArray(b'tiff'), PyQt5.QtCore.QByteArray(b'wbmp'), PyQt5.QtCore.QByteArray(b'webp'), PyQt5.QtCore.QByteArray(b'xbm'), PyQt5.QtCore.QByteArray(b'xpm')]
    里面是有jpeg的。
    但是Pyside2那段代码的结果是:
    [PySide2.QtCore.QByteArray(b'bmp'), PySide2.QtCore.QByteArray(b'pbm'), PySide2.QtCore.QByteArray(b'pgm'), PySide2.QtCore.QByteArray(b'png'), PySide2.QtCore.QByteArray(b'ppm'), PySide2.QtCore.QByteArray(b'xbm'), PySide2.QtCore.QByteArray(b'xpm')]
    可以看到,里面没有jpg,难怪jpg的图片无法显示。
  • 然后我继续在网上搜索,在一个贴吧里(地址:https://tieba.baidu.com/p/7130333819)看到有贴吧大佬提示可能是dll加载异常,建议加上一行
QtCore.QCoreApplication.addLibraryPath(os.path.join(os.path.dirname(QtCore.__file__), "plugins"))

我照着做了,但是还是不行。

  • 我想看看这个路径里到底是啥东西,于是在代码里加上一行print(os.path.dirname(QtCore.__file__)),输出结果是C:\Anaconda3\envs\pytorch_py37\lib\site-packages\PySide2,这个结果其实就是anaconda环境下Pyside2的包,打开该文件夹的plugins文件夹,可以看到里面有个imageformats文件夹,里面是:
    在这里插入图片描述
    里面有一个qjpeg.dll,显然贴吧大佬说的应该就是这个dll了。
  • 同时,我在StackOverflow上(地址:https://stackoverflow.com/questions/10739758/qlabel-wont-load-a-pixmap-if-it-is-a-jpg-image)看到,加载qjpeg.dll库是通过app.addLibraryPath(path)实现的(这个老外还提到路径只需要放在plugins这一级,不要放在plugins/imageformats下),于是我改了一下贴吧大佬给出的那一行代码如下:
app.addLibraryPath(os.path.join(os.path.dirname(QtCore.__file__), "plugins"))
  • 终于,PySide2成功地在QLabel中显示jpg图片了。。。。

不知是否还有其他小伙伴也遇到了这个问题,希望能有所帮助,欢迎在评论区交流。

参考资料:

  • https://doc.qt.io/qt-5/qpixmap.html#QPixmap-2
  • https://doc.qt.io/qt-5/qpixmap.html#reading-and-writing-image-files
  • https://tieba.baidu.com/p/7130333819#136830331399l
  • https://stackoverflow.com/questions/50209879/how-to-load-an-image-with-qlabel-in-pyside2
  • https://stackoverflow.com/questions/10739758/qlabel-wont-load-a-pixmap-if-it-is-a-jpg-image
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐