之前一直是用PyQt5的,最近的项目由于担心开源协议的问题,开始使用PySide2,没想到在简单的图片显示上就出现了问题。 问题的表现是这样的,对于有的.jpg图片,使用PyQt5是完全可以正常显示的,但是一旦换成PySide2就不行。
由于后面内容较长,所以先说解决方法:
- 出现此问题可能是用于支持jpg的dll动态链接库没有加载成功;
- 可以通过在代码中
app = QApplication(sys.argv) 后追加一行app.addLibraryPath(os.path.join(os.path.dirname(QtCore.__file__), "plugins")) 手动添加动态链接库予以解决。
给出两段示例代码。 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
|