在基于Conda的 Python环境中,如何在VSCode中定位产生冲突的库?
我在VSCode的 Conda环境中运行Python。在尝试绘制一个numpy对象时,Python崩溃了(不是VSCode),错误信息如下:
Cannot mix incompatible Qt library (5.15.15) with this library (5.15.8)
导致崩溃的那一行是:
plt.imshow(t2)
我的Python代码包括:
from osgeo import gdal
import numpy as np
import pandas as pd
import xarray as xr
import rioxarray as rxr
import rasterio as rio
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
import matplotlib.patches as mpatches
import os
但我没有导入PyQt或 Qt等。我在想到底是Qt的哪些版本混在一起,以及如何解决这个问题。我在一台Windows 10机器上。这是我的Conda环境:
conda list
# packages in environment at C:\Users\jp\AppData\Local\miniconda3\envs\netcdf:
#
# Name Version Build Channel
_openmp_mutex 4.5 20_gnu conda-forge
affine 2.4.0 py314haa95532_0
attrs 26.1.0 py314h35db113_0
beautifulsoup4 4.14.3 py314haa95532_0
blosc 1.21.6 hfd34d9b_1 conda-forge
brotlicffi 1.2.0.0 py314h885b0b7_0
bzip2 1.0.8 h0ad9c76_9 conda-forge
ca-certificates 2026.3.19 haa95532_0
certifi 2026.01.04 py314haa95532_0
cffi 2.0.0 py314h02ab6af_1
cftime 1.6.5 py314h2b7f5b3_0
charset-normalizer 3.4.4 py314haa95532_0
click 8.0.3 pyhd3eb1b0_0
cligj 0.7.2 pyhd3eb1b0_0
contourpy 1.3.3 py314h214f63a_0
cycler 0.12.1 py314haa95532_0
fonttools 4.62.1 py314h1c6eee0_0
freetype 2.14.1 hfbffc0b_0
freexl 2.0.0 hf297d47_2 conda-forge
gdal 3.11.4 py314h14fb65b_2
geos 3.14.1 hdade9fe_0 conda-forge
gst-plugins-base 1.26.10 h637b033_0
gstreamer 1.26.10 hfa53c27_0
gstreamer-orc 0.4.42 h614cf89_0
hdf4 4.2.15 h5557f11_7 conda-forge
hdf5 1.14.6 nompi_hae35d4c_106 conda-forge
icu 78.3 h637d24d_0 conda-forge
idna 3.11 py314haa95532_0
kiwisolver 1.4.9 py314h03f52e7_0
krb5 1.21.3 h885b0b7_4
lcms2 2.18 hf2c6c5f_0 conda-forge
lerc 4.1.0 hd936e49_0 conda-forge
libaec 1.1.6 hdd710a1_0
libarchive 3.8.6 gpl_he24518a_100 conda-forge
libblas 3.11.0 6_hf2e6a31_mkl conda-forge
libbrotlicommon 1.2.0 hfd05255_1 conda-forge
libbrotlidec 1.2.0 hfd05255_1 conda-forge
libbrotlienc 1.2.0 hfd05255_1 conda-forge
libcblas 3.11.0 6_h2a3cdd5_mkl conda-forge
libclang13 22.1.2 default_h463168d_0
libcurl 8.18.0 h43ecb02_0 conda-forge
libdeflate 1.25 h51727cc_0 conda-forge
libexpat 2.7.5 hac47afa_0 conda-forge
libffi 3.5.2 h3d046cb_0 conda-forge
libfreetype 2.14.1 h57928b3_0 conda-forge
libfreetype6 2.14.1 hdbac1cb_0 conda-forge
libgcc 15.2.0 h8ee18e1_18 conda-forge
libgdal-core 3.11.4 h9732b15_9 conda-forge
libglib 2.86.3 h9bccc14_0
libgomp 15.2.0 h8ee18e1_18 conda-forge
libhwloc 2.12.2 default_h4379cf1_1000 conda-forge
libhwy 1.3.0 ha71e874_1 conda-forge
libiconv 1.18 hc1393d2_2 conda-forge
libjpeg-turbo 3.1.2 hfd05255_0 conda-forge
libjxl 0.11.2 hf3f85d1_0 conda-forge
libkml 1.3.0 h68a222c_1022 conda-forge
libkrb5 1.21.3 h885b0b7_4
liblapack 3.11.0 6_hf9ab0e9_mkl conda-forge
libllvm22 22.1.2 h627c154_0
liblzma 5.8.2 hfd05255_0 conda-forge
libmpdec 4.0.0 hfd05255_1 conda-forge
libnetcdf 4.9.3 nompi_h3948bcf_104 conda-forge
libopenjpeg 2.5.4 h02ab6af_1
libpng 1.6.57 h7351971_0 conda-forge
librttopo 1.1.0 haa95264_20 conda-forge
libspatialite 5.1.0 gpl_h0cd62ae_119 conda-forge
libsqlite 3.52.0 hf5d6505_0 conda-forge
libssh2 1.11.1 h9aa295b_0 conda-forge
libtiff 4.7.1 h8f73337_1 conda-forge
libwebp-base 1.6.0 h4d5522a_0 conda-forge
libwinpthread 12.0.0.r4.gg4f2fc60ca h57928b3_10 conda-forge
libxcb 1.17.0 h0e4246c_0 conda-forge
libxml2 2.15.2 h779ef1b_0 conda-forge
libxml2-16 2.15.2 h3cfd58e_0 conda-forge
libxml2-devel 2.15.2 h779ef1b_0 conda-forge
libzip 1.11.2 h3135430_0 conda-forge
libzlib 1.3.2 hfd05255_2 conda-forge
llvm-openmp 22.1.3 h4fa8253_0 conda-forge
lz4-c 1.10.0 h2466b09_1 conda-forge
lzo 2.10 h6a83c73_1002 conda-forge
matplotlib 3.10.8 py314haa95532_0
matplotlib-base 3.10.8 py314h7ae407a_0
minizip 4.0.10 h9fa1bad_0 conda-forge
mkl 2025.3.1 hac47afa_11 conda-forge
muparser 2.3.5 he0c23c2_0 conda-forge
narwhals 2.7.0 py314haa95532_0
netcdf4 1.7.2 py314h7bfb57d_2
numpy 2.3.5 py314h06c3c77_1 conda-forge
openjpeg 2.5.4 h56d5a42_1
openssl 3.6.2 hf411b9b_0 conda-forge
packaging 26.0 py314haa95532_0
pandas 3.0.2 py314hf1216d0_0
pcre2 10.46 h5740b90_0
pillow 12.1.1 py314h61b30b5_0 conda-forge
pip 26.0.1 pyh145f28c_0 conda-forge
plotly 6.6.0 py314h56ec5ee_0
proj 9.7.1 hd30e2cd_3 conda-forge
pthread-stubs 0.3 h3c9f919_1
pycparser 3.0 py314haa95532_0
pyparsing 3.2.5 py314haa95532_0
pyproj 3.7.2 py314h2414024_0
pyqt 5.15.11 py314h816affc_0
pyqt5-sip 12.17.0 py314h02ab6af_0
pysocks 1.7.1 py314haa95532_1
python 3.14.4 h4b44e0e_100_cp314 conda-forge
python-dateutil 2.9.0post0 py314haa95532_2
python-tzdata 2025.3 pyhd3eb1b0_0
python_abi 3.14 2_cp314
qt-main 5.15.15 he584256_7 conda-forge
rasterio 1.5.0 py314hc9c6987_0
requests 2.33.1 py314haa95532_0
rioxarray 0.22.0 py314haa95532_0
setuptools 82.0.1 py314haa95532_0
sip 6.12.0 py314h706e071_0
six 1.17.0 py314haa95532_0
snappy 1.2.2 h7fa0ca8_1 conda-forge
soupsieve 2.5 py314haa95532_0
sqlite 3.52.0 hdb435a2_0 conda-forge
tbb 2022.3.0 h3155e25_2 conda-forge
tk 8.6.13 h6ed50ae_3 conda-forge
tornado 6.5.5 py314h1c6eee0_0
typing-extensions 4.15.0 py314haa95532_0
typing_extensions 4.15.0 py314haa95532_0
tzdata 2025c hc9c84f9_1 conda-forge
ucrt 10.0.26100.0 h57928b3_0 conda-forge
uriparser 0.9.8 h5a68840_0 conda-forge
urllib3 2.6.3 py314haa95532_0
vc 14.3 h41ae7f8_34 conda-forge
vc14_runtime 14.44.35208 h818238b_34 conda-forge
vcomp14 14.44.35208 h818238b_34 conda-forge
win_inet_pton 1.1.0 py314haa95532_1
xarray 2026.2.0 py314haa95532_0
xerces-c 3.3.0 hac47afa_1 conda-forge
xorg-libxau 1.0.12 hba3369d_1 conda-forge
xorg-libxdmcp 1.1.5 hba3369d_1 conda-forge
zlib 1.3.2 hfd05255_2 conda-forge
zlib-ng 2.3.3 h0261ad2_1 conda-forge
zstd 1.5.7 h534d264_6 conda-forge
我的Conda环境确实有Qt 5.15.15,但我不知道错误指的是Qt 5.15.8的哪一个版本,亦或是在何处引用,因此不知道如何解决这个冲突。我应该在哪儿查找第二个版本,或者更好的说,如何解决这个冲突?
解决方案
关于Qt与 Python绑定的一些背景信息
Qt是一个C++库,不能直接在Python中使用。
有两种已知的让Python使用Qt的绑定:PyQt(由个人维护)和PySide(也称为“Qt for Python”,由Qt官方维护)。
还有一些 [shim](参见https://en.wikipedia.org/wiki/Shim_(computing))可以在Python中透明使用Qt,无论安装了哪种绑定或Qt版本,最终都会根据环境导入最合适的绑定/版本。
但请记住:
- 每个进程只能使用一个绑定:理论上有时可能做到,但你永远不应该同时使用PyQt和 PySide;
- 绑定应始终针对相同的API/ABI。
第二点非常相关,因为你甚至可能拥有相同的 [Py]Qt版本,但它们可能并不兼容。
但你也可能有两个或以上的PyQt安装,恰好使用了相同的二进制文件,从而隐式兼容。
重点是:无论你使用什么,一旦某个绑定“导入”了一个Qt版本,那么只能使用那个版本。
找出元凶
至少你的两个导入中的某些实际上试图隐式导入上述某个已在某个时点安装的Python绑定,但它们并不兼容。
你可能在Conda环境内外分别安装了PyQt5,或另一个模块在没有正确检查环境,或无法正确验证整个环境的情况下自动安装了相应的PyQt绑定。
你的设置其实已经坏掉了。
你可以通过检查 [sys.modules] 来查看导入的模块。
检查PyQt5是否已被导入的最简单测试如下所示:
import sys
for name, mod in sys.modules.items():
if name == 'PyQt5':
print('PyQt', mod.QtCore.PYQT_VERSION_STR)
print('Qt', mod.QtCore.QT_VERSION_STR)
break
注:PyQt的 minor 版本和 build/maintenance 版本号很少与相关Qt版本号一致;PySide的版本号通常与Qt版本对应关系更为一致,但也不能因此就理所当然。
理论上,上面的输出应该根本不显示任何内容。
如果真的有输出,说明你的环境隐式导入了一些也会导入PyQt绑定的东西。
若是这样,你还应该在末尾追加一个最终的 print(sys.modules),以便检查任何意外的导入。
你还应该在Conda环境内外都尝试同样的代码。
如果没有输出,请通过在可能导致PyQt导入的每个模块前添加一个 import,向后回溯导入序列。
最先怀疑的当然是matplotlib,它确实会在找到Qt时导入它。
把下面这行添加到上面代码的顶部,然后看看结果:
import matplotlib.pyplot
然后再次重复操作,并将上述行改为你在matplotlib之前的所有其他导入:你可能会发现究竟是哪些模块实际导入了不同的Qt版本。
需要注意的是,不同的模块可能会决定偏向某个绑定。
事实上,很可能某个模块导入了PyQt,另一个导入了PySide,甚至它们中的某些导入了一个 不同的Qt主版本,在某些情况下即使只使用其中一个,导入两者也可能引发问题。
作为进一步的安全检查,你可以将上面的改成如下形式:
import sys
for name, mod in sys.modules.items():
if name.startswith('PyQt') and not '.' in name:
print(
'PyQt', mod.QtCore.PYQT_VERSION_STR,
'Qt', mod.QtCore.QT_VERSION_STR
)
elif name.startswith('PySide') and not '.' in name:
print(
'PySide', mod.__version__,
'Qt', mod.QtCore.__version__
)
解决这个问题
上述不一致可能难以解决。某些模块可能由于维护不善或内部选择而不支持较新版本。
你甚至可能需要要求一个低于你偏好的Qt(或绑定)版本。
无论如何,第一步是找出你设置中的不一致之处(可能是在Conda环境内外安装的模块/包所致)。如果你解决了这一点,你很可能已经解决了大多数人可能遇到的问题,只要你的应用包考虑到你所期望的一致性和整体环境,包括应用的部署阶段。