回答:
ここでは、PyQGIS APIの下で何が新しく、何が壊れているかを見つけることができます。
python3にどのポートPython2の詳細を取得するには、そこに行きます
この質問については、QGIS2からQGIS3へのテストに関する詳細を見つけることができます:QGISプラグインの自動テストの作成?
また、移行ツールに関するOpenGis.chの興味深い論文がここにあります。
実際、新しいバージョンを渡す準備ができていないプラグインのコードを変更する必要があります。
QGISバージョンを確認するために作成されたqgis.utils.QGis.QGIS_VERSION_INT関数を取得します。これは、関数がデキャブルされている場合に役立ちます。exempleについては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は、新しいスタイルの信号とスロットのハンドライトのみをサポートします。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のドキュメントを確認する必要があり
ます。PyQt5QtCore モジュール
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のサポートを参照)。アプリケーション開発者は通常、これをQtWidgetsモジュールに含まれるような高レベルのAPIで使用します。
そして、PyQt5は新しいスタイルのシグナルとスロットのハンドライトのみをサポートします!このページを見てい使用方法を理解するためpyqtSignal
、connect
およびe
イベントオブジェクトの代わりに使用しますSIGNAL
。
そのため、PyQt4 / PyQt5(およびQGIS2 / QGIS3)間の互換性があるため、pyQt5ライブラリを使用する前にインポートを試す/除外する必要があります。
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を開き、QGIS内でPythonコンソールを開きます-> QGIS全体が即座にクラッシュします!
いくつかのテストを行った結果、resources.py
上記の小さな変更が原因であることがわかりました。私はQGIS Pythonライブラリの専門家ではありませんが、私の説明は次のとおりです。
QGISを開くと、プラグインが初期化されます。やろうとする試みfrom PyQt5 import QtCore
すると、間違ったバージョンのPyQtが例外を発生させる前に、QGISの「ワークフロー」にいくつかの変更が発生します(これはRuntimeError
)。Pythonコンソールを起動すると、これらの変更により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
、これはそう何のtry-除く輸入が必要とされ、移行スクリプトは、(モジュールが変更に必要な調整を含む)が適切に最後のステップを間に合わせるんだろう。