Hem sürüm 2.x hem de 3.x için QGIS python eklentisi yap?


12

QGIS python eklentisini 'den' QGIS 2e geçirme QGIS 3ve çeşitli kaynaklara göz atma sürecindeyim .

Eklentinin her iki sürümle de uyumlu olup olmadığı veya eklenti sürümleri için iki tutamak gerekli olup olmadığı açık değildir.

Şimdiye kadar vurduğum sorun PyQt içe aktarma (PyQt4 / PyQt5) nasıl yönetilir?

Yanıtlar:


18

belgeleme

Burada yeni ve neyin kırıldığını PyQGIS API'sinde bulabilirsiniz .
Python2'yi Python3'e nasıl taşıyacağınız hakkında bilgi almak için oraya gidin

QGIS2'den QGIS3'e test hakkında şu soru hakkında ayrıntılı bilgi bulabilirsiniz: QGIS eklentileri için otomatik testler mi yazıyorsunuz ?

Burada , taşıma araçları hakkında ilginç bir OpenGis.ch makalesi bulacaksınız .

Koduma ne değişecek

Aslında, yeni bir sürümü geçmeye hazır olmayan eklenti kodunu değiştirmeniz gerekir.

QGIS sürümünü kontrol etmek için yapılan qgis.utils.QGis.QGIS_VERSION_INT işlevini alırsınız . Bir işlev kullanımdan kaldırıldığında bu yararlıdır. 2.16'dan setSelectedFeaturesberi örnek için .

İfadenin kullanımı ile örnek olarak 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 ] )

PyQtModülünüz altında içe aktardığınız nesne ile aynıdır . Uyumluluğa ihtiyacınız varsa, fiyat daha fazla kod satırı yazacaktır (QGIS2 işlevli kod ve QGIS3 işlevli kod VE ayrıca sürümü ve yeni kitaplıkları içe aktarma yeteneklerini kontrol etme kodu).

PyQt kütüphaneleri hakkında

PyQt5, PyQt4 ile geriye dönük olarak uyumlu değildir; PyQt5'te birkaç önemli değişiklik var. Ancak, eski kodu yeni kitaplığa ayarlamak çok zor değildir. Farklılıklar, diğerlerinin yanı sıra, aşağıdakilerdir:

  • Python modülleri yeniden düzenlendi. Bazı modüller bırakıldı (QtScript), diğerleri alt modüllere (QtGui, QtWebKit) ayrıldı.

  • QtBluetooth, QtPositioning veya Enginio dahil olmak üzere yeni modüller piyasaya sürüldü.

  • PyQt5 yalnızca yeni stil sinyalini ve yuvaları handlig'i destekler. SIGNAL () veya SLOT () çağrıları artık desteklenmiyor. PyQt5, Qt API'sinin Qt v5.0'da kullanım dışı veya eski olarak işaretlenmiş hiçbir bölümünü desteklemez.

kaynak: ( http://zetcode.com/gui/pyqt5/introduction/ )

İşte / import ifadenizdeki değişikliklere ilişkin bazı örnekler:

PyQt4 ile API'nın belgesine bakmanız gerektiğini hatırlayın :
örnek
PyQT4 QtCore modülü için
PyQT4 QtGui modülü

from PyQt4.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QObject, SIGNAL

from PyQt4.QtGui import QAction, QIcon, QDialog, QFormLayout

Ve PyQt5 ile şimdi bu API'nın dokümanı:
PyQt5 QtCore modülü
PyQt5 QtGui modülü

böylece:

from PyQt5.QtCore import QSettings, QTranslator, QVersionNumber, QCoreApplication, Qt, QObject, pyqtSignal 
from PyQt5.QtGui import QIcon 
from PyQt5.QtWidgets import QAction, QDialog, QFormLayout

Bunu not et :

QtGui modülü alt modüllere ayrılmıştır. QtGui modülü pencereleme sistemi entegrasyonu, olay işleme, 2D grafikler, temel görüntüleme, yazı tipleri ve metin sınıfları içerir. Ayrıca eksiksiz bir OpenGL ve OpenGL ES bağlamaları seti içerir (bkz . OpenGL Desteği ). Uygulama geliştiricileri bunu normalde QtWidgets modülünde bulunanlar gibi daha üst düzey API'lerle kullanırlar.

Ve PyQt5 sadece yeni stil sinyal ve yuvaları handlig destekler! Bir bu sayfayı göz nasıl kullanılacağını anlamak için pyqtSignal, connectve eolay nesnesini yerine kullanılmasını SIGNAL.

Uyumlu hale getirin

Bu nedenle PyQt4 / PyQt5 (ve QGIS2 / QGIS3) arasındaki uyumluluk ile pyQt5 kütüphanesini kullanmadan önce içe aktarmayı denemeniz / hariç tutmanız gerekir.

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

Ayrıca, try / hariç veya if ifadesi ekleyerek kodunuzun altındaki bazı belirli işlevleri de değiştirmeniz gerektiğini unutmayın.


2
Güzel cevap, büyük ölçüde yardım birinci herhangi değiştirmektir bir şey from PyQt4.QtCore import *ile from PyQt4.QtCore import QSomething, QWhatever, QElsebu taşıma Senaryo çok hayır, düzgün (modüller değiştirildi gerekli ayarlamaları dahil) son adımı yapacak deneyin-hariç ithalatı ihtiyaç vardır.
Matthias Kuhn

Haklısın * basit tutmak için kullandım, ama bunu değiştireceğim, geri bildiriminiz için teşekkürler
Hugo Roussaffa - GeoDatup

Bu konu insanlara * -import kullanmamalarını söylemek için mükemmel bir yer, çünkü burada aslında bir fark yaratıyor
Matthias Kuhn

@Hugo: Gerçekten çok ayrıntılı bir cevap, başlamak için çok yardımcı oldu. Qgis2compat eklentisini daha önce değinilen çok sayıda faydalı kaynağa ekleyeceğim .
1717

Bu harika fikir. Cevabı istediğiniz gibi düzenleyebilirsiniz. Geri bildiriminiz için teşekkürler
Hugo Roussaffa - GeoDatup

2

Böyle bir şey deneyin:

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

Bu, bazı yalıtılmış şeyler için işe yarayabilir, ancak genellikle genel bir çözüm olarak çalışmaz.
Matthias Kuhn

1

QGIS Python eklentisini taşımayı bitirdim, böylece hem 2.x hem de 3.x QGIS sürümlerini destekliyor. İşte benim deneyimim:

Çoğunlukla QGIS versiyonuna güvenmeye çalıştım. Ama sürümü tutan sınıf bile biraz yeniden adlandırıldı. Bu yüzden önce yaptım

try:
    from qgis.utils import Qgis  # for QGIS 3
except ImportError:
    from qgis.utils import QGis as Qgis  #  for QGIS 2

ve sonra kontroller yap

if Qgis.QGIS_VERSION >= '3.0':
    # something for QGIS 3
else:
    # something for QGIS 2

Son bir sürümü dağıttıktan sonra resources.py, otomatik olarak oluşturulan bir dosyanın pyrcc5da taşınması gerektiğini fark ettim . Aksi takdirde eklenti 2.x'de bozulmaya devam edecektir. Bu yüzden çizgisini değiştirdim

from PyQt5 import QtCore

için

try:
    from PyQt5 import QtCore
except:
    from PyQt4 import QtCore

İşe yaramış gibi görünüyordu. Resmi bir açıklama yaptım ve öyle olduğunu düşündüm. Ancak o zaman bu diziyi keşfettim:

Eklentimi QGIS 2.18'e yükle, QGIS'i kapat, QGIS'i aç ve ardından QGIS içinde Python Konsolu aç -> Tüm QGIS anında çökecek!

Bazı testlerden sonra sebebinin resources.pyyukarıda yazılı olan bu küçük değişiklik olduğunu öğrendim . QGIS Python kütüphanelerinde uzman değilim ama açıklamam şudur:

QGIS'i açtığımda eklentim başlatılır. Yapmanın girişimi from PyQt5 import QtCoreistisna (bir oldu yükseltir yanlış PyQT versiyonundan önce QGIS "iş akışı" in nedenlerini bazı değişiklikler RuntimeError). Python Konsolu'nu başlattığımda bu değişiklikler QGIS'in çökmesine neden oluyor.

Sonunda farklı bir çözüme karar verdim. QGIS 2 Python 2.7 kullandığından ve QGIS 3 Python 3 kullandığından Python sürümü için her zaman kontrol yaparım .

from sys import version_info

if version_info[0] >= 3:
    # something for QGIS 3
else:
    # something for QGIS 2

Bu, potansiyel olarak zararlı tüm ithalat girişimlerini önler. Eklentim artık her iki QGIS sürümünde de sorunsuz çalışıyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.