दोनों संस्करणों 2.x और 3.x के लिए QGIS पायथन प्लगइन बनाएं?


12

मैं विभिन्न संसाधनों को ब्राउज़ QGIS 2करने QGIS 3और ब्राउज़ करने से लेकर QGIS पायथन प्लगइन के माइग्रेशन की प्रक्रिया में हूं ।

यह स्पष्ट नहीं है कि क्या प्लगइन को दोनों संस्करणों के साथ संगत करना संभव है या यदि यह प्लगइन संस्करणों के लिए दो संभाल आवश्यक है।

अब तक मैंने जो समस्या पेश की है वह यह है कि PyQt आयात (PyQt4 / PyQt5) को कैसे प्रबंधित किया जाए?

जवाबों:


18

प्रलेखन

यहां आप पा सकते हैं कि PyQGIS API के तहत नया क्या है और क्या है
Python2 को Python3 में पोर्ट करने के तरीके के बारे में विवरण प्राप्त करने के लिए वहां जाएं

आप इस प्रश्न पर QGIS2 से QGIS3 तक परीक्षण के बारे में कुछ विवरण पा सकते हैं: QGIS प्लगइन्स के लिए स्वचालित परीक्षण लिखना?

और आपको यहां माइग्रेशन टूल के बारे में एक दिलचस्प ओपनगिस.च पेपर मिल जाएगा ।

मेरे कोड में क्या परिवर्तन होगा

वास्तव में, आपको प्लगइन के कोड को बदलने की आवश्यकता है जो एक नए संस्करण से गुजरने के लिए तैयार नहीं हैं।

आपको qgis.utils.QGis.QGIS_VERSION_INT फ़ंक्शन मिलता है जो QGI संस्करण की जाँच करने के लिए बनाया गया है। यह तब उपयोगी होता है जब कोई फ़ंक्शन डिप्रेसेबल होता है। उदाहरण के लिए 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, QtWebKK) में विभाजित किया गया है।

  • नए मॉड्यूल पेश किए गए हैं, जिनमें QtBlu ब्लूटूथ, QtPositioning, या Enginio शामिल हैं।

  • PyQt5 केवल नए-स्टाइल सिग्नल और स्लॉट्स हैंडलिग का समर्थन करता है। SIGNAL () या SLOT () के लिए कॉल अब समर्थित नहीं हैं। PyQt5 Qt एपीआई के किसी भी हिस्से का समर्थन नहीं करता है जो Qt v5.0 में पदावनत या अप्रचलित के रूप में चिह्नित हैं।

स्रोत: ( http://zetcode.com/gui/pyqt5/introduction/ )

यहाँ आपके / आयात विवरण से परिवर्तन के कुछ उदाहरण हैं:

PyQt4 के साथ याद रखें कि आपको एपीआई के डॉक पर देखना था:
उदाहरण के लिए
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 मॉड्यूल में निहित के साथ इसका उपयोग करेंगे।

और PyQt5 केवल नए-शैली के संकेत और स्लॉट हैंडलिग का समर्थन करता है! उपयोग करने के लिए कैसे उपयोग करें , और ईवेंट ऑब्जेक्ट को समझने के लिए इस पृष्ठ पर एक नज़र डालेंpyqtSignalconnecteSIGNAL

इसे संगत बनाएं

तो 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

और यह मत भूलो कि आपको अपने कोड के तहत कुछ विशिष्ट फ़ंक्शन को भी प्रयास / जोड़कर या यदि कथन में बदलना है।


2
महान जवाब, कुछ ऐसा जो बहुत मदद करेगा, पहले किसी के from PyQt4.QtCore import *साथ बदलने के लिए है from PyQt4.QtCore import QSomething, QWhatever, QElse, यह माइग्रेशन स्क्रिप्ट को अंतिम चरण ठीक से करेगा (आवश्यक समायोजन जहां मॉड्यूल बदल गए हैं), इसलिए कोई भी प्रयास-छोड़कर आयात की आवश्यकता नहीं है।
मथायस कुह्न

आप सही हैं मैं इसे सरल रखने के लिए * का उपयोग करता हूं, लेकिन मैं इसे बदल दूंगा, आपकी प्रतिक्रिया के लिए धन्यवाद
ह्यूगो रूससा - जियोडाटअप

यह विषय लोगों को यह बताने के लिए सही जगह है कि वे * -पोर्ट का उपयोग न करें, क्योंकि यहाँ वास्तव में फर्क पड़ता है
मथायस कुह्न

@ ह्यूगो: वास्तव में बहुत विस्तृत उत्तर, इसने शुरुआत करने में बहुत मदद की। मैं पहले से उद्धृत कई उपयोगी संसाधनों के लिए qgis2compat प्लगइन जोड़ूंगा
sigeal

एक यह जबरदस्त आइडिया है। जैसा आप चाहते हैं आप उत्तर को संपादित कर सकते हैं। प्रतिक्रिया के लिए धन्यवाद
ह्यूगो रूससा - जियोडाटअप

2

कुछ इस तरह की कोशिश करो:

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

यह कुछ अलग-थलग चीजों के लिए काम कर सकता है लेकिन अक्सर एक सामान्य समाधान के रूप में काम नहीं करेगा।
मथायस कुह्न

1

मैंने अभी-अभी एक QGIS पायथन प्लगइन को पोर्ट करना समाप्त किया है ताकि यह अब 2.x और 3.x 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 के अंदर पायथन कंसोल खोलें -> संपूर्ण QGIS तुरंत दुर्घटनाग्रस्त हो जाएगा!

कुछ परीक्षण के बाद मुझे पता चला कि resources.pyऊपर लिखित में यह छोटा परिवर्तन था । मैं QGIS पायथन पुस्तकालयों में कोई विशेषज्ञ नहीं हूं, लेकिन मेरी व्याख्या निम्नलिखित है:

जब मैं QGIS खोलता हूं तो मेरा प्लगइन इनिशियलाइज़ हो जाता है। from PyQt5 import QtCoreगलत PyQt संस्करण अपवाद (इससे पहले RuntimeError) उठाता है, इससे पहले QGIS "वर्कफ़्लो" में कुछ बदलाव करने का प्रयास करता है । जब मैं पायथन कंसोल शुरू करता हूं तो उन परिवर्तनों के कारण 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 संस्करणों पर काम करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.