버전 2.x 및 3.x 모두에 대해 QGIS python 플러그인을 작성합니까?


12

QGIS python 플러그인을에서 (으) QGIS 2로 마이그레이션하고 QGIS 3다양한 리소스를 탐색하는 중입니다.

플러그인이 두 버전 모두와 호환되는지 또는 플러그인 버전에 두 개의 핸들이 필요한지 확실하지 않습니다.

내가 지금까지 겪은 문제는 PyQt 가져 오기 (PyQt4 / PyQt5)를 관리하는 방법입니다.

답변:


18

선적 서류 비치

PyQGIS API에서 새로운 기능과 최신 기능을 확인할 수 있습니다 .
포트에 Python3에 Python2 방법에 대한 세부 정보를 얻으려면 갈이

이 질문에서 QGIS2에서 QGIS3 로의 테스트에 대한 세부 사항을 찾을 수 있습니다. QGIS 플러그인에 대한 자동 테스트 작성?

그리고 마이그레이션 도구에 대한 흥미로운 OpenGis.ch의 논문 을 찾을 수 있습니다.

내 코드로 변경되는 내용

실제로 새 버전을 통과 할 준비가되지 않은 플러그인 코드를 변경해야합니다.

QGIS 버전을 확인하기 위해 qgis.utils.QGis.QGIS_VERSION_INT 함수를 얻 습니다 . 이 기능은 더 이상 사용되지 않을 때 유용합니다. setSelectedFeatures2.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 기능이있는 코드 및 버전 및 새 라이브러리를 가져 오는 기능을 확인하는 코드)을 작성하는 것입니다.

PyQt 라이브러리 정보

PyQt5는 PyQt4와 역 호환되지 않습니다. PyQt5에는 몇 가지 중요한 변경 사항이 있습니다. 그러나 이전 코드를 새 라이브러리로 조정하는 것은 그리 어렵지 않습니다. 차이점은 다음과 같습니다.

  • 파이썬 모듈이 재구성되었습니다. 일부 모듈은 삭제되었고 (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 지원 참조 ). 애플리케이션 개발자는 일반적으로 QtWidgets 모듈에 포함 된 것과 같은 상위 레벨 API와 함께이를 사용합니다.

PyQt5는 새로운 스타일의 신호 및 슬롯 handlig 만 지원합니다! 페이지보기가 사용하는 방법을 이해하기 위해 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 문을 추가하여 코드에서 특정 기능을 변경해야한다는 것을 잊지 마십시오.


2
큰 대답은 크게 도움이 될 것입니다. 먼저를로 바꾸는 것 from PyQt4.QtCore import *입니다 from PyQt4.QtCore import QSomething, QWhatever, QElse. 이것은 마이그레이션 스크립트가 마지막 단계를 올바르게 수행하게합니다 (모듈이 변경된 위치의 필수 조정 포함). 따라서 가져 오기 제외는 필요하지 않습니다.
Matthias Kuhn

당신이 옳았습니다 * 간단하게하기 위해 사용했지만 여러분의 의견에 감사드립니다
Hugo Roussaffa-GeoDatup

이 주제는 사람들에게 * -imports를 사용하지 말라고 알려주는 완벽한 장소입니다. 여기서 실제로 차이를 만들기 때문입니다.
Matthias Kuhn

@ Hugo : 매우 자세한 답변은 실제로 시작하는 데 많은 도움이되었습니다. 이미 인용 된 수많은 유용한 리소스에 qgis2compat 플러그인을 추가 하겠습니다 .
sigeal

좋은 생각입니다. 원하는대로 답변을 편집 할 수 있습니다. 피드백을 주셔서 감사합니다
휴고 Roussaffa - GeoDatup

2

그런 것을 시도하십시오 :

try:
    # action for QGIS 3/PyQt5
except:
    # action for QGIS 2/PyQt4

이것은 고립 된 것들에 대해서는 효과가 있지만 일반적인 솔루션으로는 효과가없는 경우가 많습니다.
Matthias Kuhn

1

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 Console을 엽니 다.-> 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 버전에서 아무런 문제없이 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.