Answers:
在这里,您可以找到PyQGIS API的新功能和新功能。
要获取有关如何将Python2移植到Python3的详细信息,请转到此处
您可以在以下问题上找到有关从QGIS2到QGIS3进行测试的详细信息:为QGIS插件编写自动化测试?
您将在这里找到有关迁移工具的有趣的OpenGis.ch论文。
实际上,您需要更改不准备通过新版本的插件的代码。
您将获得qgis.utils.QGis.QGIS_VERSION_INT函数,该函数用于检查QGIS版本。当不建议使用的功能时,此功能很有用。例如setSelectedFeatures
从2.16开始。
以if
语句的使用为例:
if qgis.utils.QGis.QGIS_VERSION_INT < 21600 :
joinLayer.setSelectedFeatures( [ f.id() for f in request ] )
else:
joinLayer.selectByIds( [ f.id() for f in request ] )
PyQt
您在模块下导入的对象是相同的。如果需要兼容性,价格是编写更多代码行(具有QGIS2功能的代码和具有QGIS3功能的代码,以及用于检查版本和导入新库的功能的代码)。
PyQt5与PyQt4向后不兼容。PyQt5有一些重大变化。但是,将旧代码调整为新库并不是很困难。除其他外,差异如下:
Python模块已重新组织。一些模块已被删除(QtScript),其他模块被拆分为子模块(QtGui,QtWebKit)。
引入了新模块,包括QtBluetooth,QtPositioning或Enginio。
- PyQt5仅支持新型信号和插槽handlig。不再支持对SIGNAL()或SLOT()的调用。PyQt5不支持Qt v5.0中标记为已弃用或过时的Qt API的任何部分。
来源:(http://zetcode.com/gui/pyqt5/introduction/)
以下是对您的from / import语句进行更改的一些示例:
记住使用PyQt4时,您必须查看API的文档:
例如
PyQT4 QtCore模块
PyQT4 QtGui模块
from PyQt4.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QObject, SIGNAL
from PyQt4.QtGui import QAction, QIcon, QDialog, QFormLayout
使用PyQt5,您现在必须查看这些API的文档:
PyQt5 QtCore模块
PyQt5 QtGui模块
这样就变成:
from PyQt5.QtCore import QSettings, QTranslator, QVersionNumber, QCoreApplication, Qt, QObject, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QDialog, QFormLayout
QtGui模块已拆分为子模块。QtGui模块包含用于窗口系统集成,事件处理,2D图形,基本图像,字体和文本的类。它还包含一套完整的OpenGL和OpenGL ES绑定(请参阅对OpenGL的支持)。应用程序开发人员通常将其与更高级别的API配合使用,例如QtWidgets模块中包含的那些API。
而且PyQt5仅支持新型信号和插槽handlig!看看这个页面来了解如何使用pyqtSignal
,connect
以及e
事件对象而不是使用SIGNAL
。
因此,为了与PyQt4 / PyQt5(以及QGIS2 / QGIS3)兼容,您需要在使用pyQt5 librarie之前先尝试/除外导入。
try:
from PyQt5.QtCore import QSettings, QTranslator, QVersionNumber, QCoreApplication, Qt, QObject, pyqtSignal
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QDialog, QFormLayout
except:
from PyQt4.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QObject, SIGNAL
from PyQt4.QtGui import QAction, QIcon, QDialog, QFormLayout
并且不要忘记,您还需要通过添加try / except或if语句来更改代码下的某些特定功能。
我刚刚完成了QGIS Python插件的移植,因此它现在支持2.x和3.x QGIS版本。这是我的经验:
通常,我试图依靠QGIS版本。但是,即使是拥有该版本的课程也被重命名了。所以我首先做了
try:
from qgis.utils import Qgis # for QGIS 3
except ImportError:
from qgis.utils import QGis as Qgis # for QGIS 2
然后进行检查
if Qgis.QGIS_VERSION >= '3.0':
# something for QGIS 3
else:
# something for QGIS 2
部署最终版本后,我注意到还需要移植resources.py
由它自动创建的文件pyrcc5
。否则,插件将在2.x中继续崩溃。所以我改变了路线
from PyQt5 import QtCore
至
try:
from PyQt5 import QtCore
except:
from PyQt4 import QtCore
看起来很有效。我正式发布了版本,并认为就是这样。直到那时我才发现这个序列:
将我的插件安装在QGIS 2.18中,关闭QGIS,打开QGIS agan,然后在QGIS中打开Python控制台->整个QGIS将立即崩溃!
经过一些测试,我发现原因是resources.py
上面写的这么小的变化。我不是QGIS Python库的专家,但我的解释如下:
当我打开QGIS时,我的插件被初始化。from PyQt5 import QtCore
在错误的PyQt版本引发异常之前,尝试这样做会导致QGIS“工作流程”发生某些变化(这是一个RuntimeError
)。当我启动Python Console时,这些更改导致QGIS崩溃。
最后,我决定采用其他解决方案。因为QGIS 2使用Python 2.7,而QGIS 3使用Python 3,所以我总是总是检查Python版本。
from sys import version_info
if version_info[0] >= 3:
# something for QGIS 3
else:
# something for QGIS 2
这样可以避免所有可能有害的导入尝试。我的插件现在可以在两个QGIS版本上正常使用了。
from PyQt4.QtCore import *
有from PyQt4.QtCore import QSomething, QWhatever, QElse
,这将使迁移脚本做最后一步正确(包括必要的调整,其中模块改变),所以没有尝试-除了需要进口。