Czy powinienem używać PyQt lub PySide do nowego projektu Qt?

59

Ostatnio brałem udział w rozmowach na temat tworzenia szablonu Quickly dla aplikacji Qt i QtQuick Ubuntu. Chodzi o to, aby tworzenie aplikacji Qt od koncepcji do pakietu było tak łatwe, jak teraz dzięki GTK, na której oparty jest szablon aplikacji Ubuntu Quickly.

Intencją jest nadal używanie Pythona jako podstawowego języka programowania, a pierwsze pytanie, które przychodzi na myśl, brzmi: które wiązania Pythona powinniśmy używać PyQt lub PySide ?

Chciałbym usłyszeć od ludzi doświadczonych w obu technologiach, jakie są zalety i wady każdego z nich, jak dobrze każdy jest utrzymany, jak dobrze mapowany jest interfejs API Qt na powiązania itp.

Dzięki!

David Planella
źródło
Python-qt4 jest w main, a python-pyside we wszechświecie. Myślę, że powinieneś prawdopodobnie zapytać o to również chłopaki Kubuntu.
Jeremy Bicha
To pytanie może być lepiej postawione na stackoverflow.com lub programmers.stackexchange.com.
DrAl
Dzięki @DrAl, tak, też się nad tym zastanawiałem, ale było to specjalnie do tworzenia szablonu Szybko dla Ubuntu, dlatego zdecydowałem się na AskUbuntu.
David Planella
Wskazano mi także na pyside.org/2012/03/pyside-becomes-a-qt-add-on
David Planella

Odpowiedzi:

63

Zarówno PyQt4, jak i PySide mają bardzo podobne odwzorowania do API Qt. Istnieją jednak pewne różnice, o których moje opinie są opisane poniżej:

Konserwacja

Oba są dobrze utrzymane. PySide wydaje obecnie o wiele więcej regularnych wydań: Myślę, że jest ściślej związany z Qt niż PyQt4, a ponieważ nowy projekt ma w tej chwili bardziej aktywną społeczność. To jednak tylko moje wrażenie i może się mylić.

PyQt4 ma dostępną opcję komercyjnego wsparcia (nie wiem, czy dotyczy to PySide, czy nie).

Licencja

PyQt4 jest wydany na licencji komercyjnej lub GPL ; PySide jest wydany na licencji LGPL . W przypadku zastosowań komercyjnych jest to znacząca różnica.

Wersje API i Python

PyQt4 obsługuje dwa różne interfejsy API. Wersja API 1 jest domyślna dla aplikacji python 2.x, a wersja API 2 jest domyślna dla aplikacji python 3.x.

PySide obsługuje tylko jeden interfejs API, który jest w przybliżeniu równoważny z interfejsem API PyQt4 w wersji 2. Interfejs API w wersji 2 (lub PySide API) jest znacznie przyjemniejszy w obsłudze niż interfejs API w PyQt4 w wersji 1. W API w wersji 1 masz dużo kodu, który rzuca python ciągi do QtCore.QStringsi ponownie. W wersji API 2 (i PySide) po prostu używasz ciągów Pythona. Poniżej znajdziesz prosty sposób przełączania między PyQt4 i PySide, jeśli chcesz grać z obydwoma.

Większość kodu, który piszę, wydaje się działać równie dobrze w PyQt4 i PySide. Historycznie zawsze używałem PyQt4 dla graficznych interfejsów Python, ale większość nowych rzeczy, które piszę, teraz korzystają z PySide (głównie ze względu na bardziej elastyczne licencjonowanie). Z pewnością polecam wypróbowanie obu i zobacz, jak je znajdziesz. Jeśli używasz QtVariant.py (poniżej), przełączanie się między nimi jest banalne, a kiedy podejmiesz decyzję, będzie tylko jeden plik, który wymaga aktualizacji.

Dokumentacja

Dokumentacja dla PyQt4 i PySide jest generowana automatycznie z głównej dokumentacji Qt . Moim zdaniem dokumentacja PySide stanowi lepszą reprezentację tego, czego faktycznie używasz, ale w praktyce zwykle i tak używam dokumentacji Qt (dość łatwo mentalnie przetłumaczyć dokumentację C ++ na python).

Biblioteki zewnętrzne

Jeśli korzystasz z bibliotek zewnętrznych, niektóre nie działają jeszcze z PySide. Szczerze mówiąc, nie ma wielu osób, które muszą współpracować z PySide, ale kilka lat temu napisałem kod wykorzystujący skręcone (z reaktorem Qt) i matplotlib, co zmusiło mnie do rezygnacji z używania PyQt4 zamiast PySide . Myślę, że jest całkiem prawdopodobne, że biblioteki te zostaną zaktualizowane do obsługi obu, ale nie sprawdziłem.

Uczynienie kodu działającym z PyQt4 lub PySide

Zakładając, że używasz języka Python 2.x, możesz dość łatwo dostosować kod do PySide i PyQt4, tworząc plik QtVariant.py i używając:

from QtVariant import QtGui, QtCore

lub cokolwiek. Plik QtVariant.py, którego używam, wygląda następująco:

import sys
import os

default_variant = 'PySide'

env_api = os.environ.get('QT_API', 'pyqt')
if '--pyside' in sys.argv:
    variant = 'PySide'
elif '--pyqt4' in sys.argv:
    variant = 'PyQt4'
elif env_api == 'pyside':
    variant = 'PySide'
elif env_api == 'pyqt':
    variant = 'PyQt4'
else:
    variant = default_variant

if variant == 'PySide':
    from PySide import QtGui, QtCore
    # This will be passed on to new versions of matplotlib
    os.environ['QT_API'] = 'pyside'
    def QtLoadUI(uifile):
        from PySide import QtUiTools
        loader = QtUiTools.QUiLoader()
        uif = QtCore.QFile(uifile)
        uif.open(QtCore.QFile.ReadOnly)
        result = loader.load(uif)
        uif.close()
        return result
elif variant == 'PyQt4':
    import sip
    api2_classes = [
            'QData', 'QDateTime', 'QString', 'QTextStream',
            'QTime', 'QUrl', 'QVariant',
            ]
    for cl in api2_classes:
        sip.setapi(cl, 2)
    from PyQt4 import QtGui, QtCore
    QtCore.Signal = QtCore.pyqtSignal
    QtCore.QString = str
    os.environ['QT_API'] = 'pyqt'
    def QtLoadUI(uifile):
        from PyQt4 import uic
        return uic.loadUi(uifile)
else:
    raise ImportError("Python Variant not specified")

__all__ = [QtGui, QtCore, QtLoadUI, variant]
DrAl
źródło
2
Ponieważ PySide często akceptuje obiekty Pythona wysokiego poziomu, twoja funkcja modułu ładującego interfejs użytkownika może zostać uproszczona do czegoś takiego return QtUiTools.QUiLoader().load(uifile), biorąc ścieżkę pliku bez żadnej płyty QFile.
Chris Billington,