برنامه نویسی | چه تفاوتی بین PyQt5 و PySide2 وجود دارد
چه تفاوتی بین PyQt5 و PySide2 وجود دارد
  • علیرضا
  • ۱۳۹۸-۰۹-۱۷
  • ۱۱۸

چه تفاوتی بین PyQt5 و PySide2 وجود دارد


اگر ساخت برنامه پایتون را با Qt5 شروع کنید ، خواهید فهمید که در واقع دو پکیج وجود دارد که می توانید برای این کار استفاده کنید - PyQt5 و PySide2.

در این پست ما این مسئله را بررسی میکنیم که چرا دو پکیج وجود دارد و تفاوت آنها در کجاست.در پایان شما میتوانید  با استفاده از  روش های که گفته میشود  ، صرف نظر از بسته ای که خودتان استفاده می کنید ،  از هر دو پکیج استفاده کنید.

زمینه

چرا دو بسته وجود دارد؟

PyQt  توسط Phil Thompson از شرکت  Riverbank Computing Ltd توسعه داده شد.. در سال 2009 ، نوکیا ، که در آن زمان صاحب ابزار Qt بود ، می خواست که اتصال های پایتون را برای Qt تحت لیسانس LGPL در دسترس قرار دهد . نتوانستند با Riverbank به توافق برسند . سپس الزامات خود را به عنوان PySide منتشر کردند

نکته: به این دلیل PySide گفته می شود که "side "  به زبان فنلاندی به معنیه  "صحافی" است

این دو رابط در ابتدا در یک سطح بودند اما در نهایت توسعه PySide از PyQt عقب ماند. این به ویژه پس از انتشار Qt 5 مورد توجه قرار گرفت - نسخه PyQt5 از اواسط سال 2016 در دسترس بود ، در حالی که اولین نسخه پایدار PySide2  دو سال بعد منتشر شد.

این تاخیر دلیلی است که چرا بسیاری از Qt 5 در پروژه های  پایتونی خود  از PyQt5 استفاده می کنند و نه PySide2 .با این حال ، پروژه Qt به تازگی PySide را به عنوان Qt رسمی برای انتشار پایتون تصویب کرده است که از دوام آن اطمینان حاصل کند و محبوبیت آن را در آینده  افزایش می دهد.

  PyQt5 PySide2
Current stable version (2019-06-23) 5.12 5.12
First stable release Apr 2016 Jul 2018
Developed by Riverbank Computing Ltd. Qt
License GPL or commercial LGPL
Platforms Python 3 Python 3 and Python 2.7 (Linux and MacOS only)

 

از کدام یک باید استفاده کنید؟ خب ، صادقانه ، واقعاً مهم نیست.

هر دو بسته در حال بکارگیری همان كتابخانه - Qt5 - هستند ، بنابراین دارای 99.9٪ API یكسان هستند (در ادامه  چند مورد را بررسی میکنیم). كدهایی كه برای یك كتابخانه نوشته شده است اغلب می توانند مانند سایر موارد استفاده كنند و فقط واردات را از PyQt5 به PySide2 تغییر می دهند. هر چیزی که برای یک کتابخانه یاد بگیرید ، با استفاده از کتاب دیگر به راحتی در یک پروژه اعمال خواهد شد.

همچنین ، مهم نیست که کدام  یک را انتخاب کنید برای استفاده ، مهم این است که خود را با دیگری آشنا کنید تا بتوانید بهترین استفاده را از کلیه منابع آنلاین موجود داشته باشید . استفاده از آموزش PyQt5 برای ساخت برنامه های PySide2 خود به عنوان مثال ، و برعکس.

در این قسمت  چند تفاوت قابل توجه بین دو بسته را اجرا می کنیم و نحوه نوشتن کدی را که یکپارچه با هر دو کار می کند توضیح خواهیم داد. پس از خواندن این باید بتوانید هر نمونه PyQt5 را بصورت آنلاین بگیرید و آن را به کار با PySide2 تبدیل کنید.

مجوز

تفاوت اصلی این دو نسخه - در واقع دلیل تمام وجود PySide2 - مجوز است. PyQt5 تحت مجوز GPL یا مجوز تجاری و PySide2 تحت مجوز LGPL موجود است.

اگر قصد دارید خود نرم افزار خود را تحت GPL منتشر کنید ، یا در حال ساختن نرم افزاری هستید که توزیع نخواهد شد ، احتمالاً استفاده از  GPL مشکلی نخواهد داشت. اما اگر قصد دارید نرم افزار خود را به صورت تجاری توزیع کنید ، لازم است مجوز تجاری را از Riverbank برای PyQt5 خریداری کنید یا از PySide2 استفاده کنید.

Qt خود تحت مجوز Qt Commercial ، GPL 2.0 ، GPL 3.0 و LGPL 3.0 در دسترس است.

نسخه های پایتون

  • PyQt5 فقط در  پایتون 3 کار میکند.
  • PySide2 برای Python3 و Python 2.7 در دسترس است ، اما نسخه های Python 2.7 فقط برای سیستم های 64 بیتی MacOS و Linux وجود دارد. ویندوز 32 بیت فقط در پایتون 2 پشتیبانی می شود.

پرونده های UI

هر دو بسته از روش هایی با  کمی تفاوت  برای بارگیری پروندههای ui ساخته  شده بوسیلیه Qt Creator / Designer استفاده می کنند. PyQt5  ، uic  را که می تواند برای بارگیری مستقیم فایلهای UI برای تولید یک شیء استفاده شود را  فراهم می کند.

import sys
from PyQt5 import QtWidgets, uic

app = QtWidgets.QApplication(sys.argv)

window = uic.loadUi("mainwindow.ui")
window.show()
app.exec()

معادل همان در  PySide2 یک خط طولانی تر است ، زیرا ابتدا باید یک شی QUILoader بسازید. متأسفانه API این دو رابط نیز متفاوت است (load  در مقابله loadUI) .

import sys
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtUiTools import QUiLoader

loader = QUiLoader()

app = QtWidgets.QApplication(sys.argv)
window = loader.load("mainwindow.ui", None)
window.show()
app.exec_()

برای بارگذاری یک UI روی یک شیء در PyQt5 ، به عنوان مثال در QMainWindow .__ init __ ، می توانید uic.loadUI را به صورت خود به خود به عنوان دومین پارامتر فراخوانی کنید.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5 import uic


class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        uic.loadUi("mainwindow.ui", self)


app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

لودر PySide2 از این روش پشتیبانی نمی کند - دومین پارامتر بارگذاری ویجت والد ویجت شما ایجاد می کنید. با این کار از افزودن کد دلخواه به بلوک __init__ ویجت جلوگیری می کنید ، اما می توانید با یک عملکرد جداگانه در این زمینه کار کنید.

import sys
from PySide2 import QtWidgets
from PySide2.QtUiTools import QUiLoader

loader = QUiLoader()

def mainwindow_setup(w):
    w.setTitle("MainWindow Title")

app = QtWidgets.QApplication(sys.argv)

window = loader.load("mainwindow.ui", None)
mainwindow_setup(window)
window.show()
app.exec()

تبدیل پرونده های UI به پایتون

هر دو كتابخانه اسكریپت های مشابهی را برای تولید ماژول های وارداتی پایتون از پرونده های Qt Designer .ui. برای PyQt5 ارائه می دهند.

pyuic5 mainwindow.ui -o MainWindow.py

می توانید با استفاده از ارث های چندگانه از کلاس پایه ای که از آن استفاده می کنید (به عنوان مثال QMainWIndow) شیء UI_MainWindow ، زیر کلاس را وارد کنید و سپس برای تنظیم UI از  self.setupUI استفاده کنین.

import sys
from PyQt5 import QtWidgets
from MainWindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi(self)


app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()

برای PySide2 نامگذاری شده است pyside2-uic :

pyside2-uic mainwindow.ui -o MainWindow.py

راه اندازی بعدی یکسان است:

import sys
from PySide2 import QtWidgets
from MainWindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setupUi(self)


app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()

exec() or exec_()

متد .exec () در Qt برای شروع حلقه رویداد از QApplication یا کادر محاوره ای شما استفاده می شود. در پایتون 2.7 exec یک کلمه کلیدی بود ، به این معنی که نمی تواند برای نام متغیر ، عملکرد یا روش استفاده شود. راه حل مورد استفاده در PyQt4 و PySide تغییر نام استفاده از .exec به .exec_ () برای جلوگیری از این درگیری بود.

پایتون 3 کلمه کلیدی exec را حذف کرد و نام را برای استفاده آزاد کرد. از آنجا که PyQt5 فقط پایتون 3 را هدف قرار می دهد ، می تواند راه حل را حذف کند ، و تماس های .exec () دقیقاً مانند خود Qt نامگذاری شوند. با این حال ، نامهای .exec_ () برای سازگاری با نسخه های قبلی حفظ شده است.

PySide2 در Python 3 و Python 2.7 موجود است و از این رو هنوز از .exec_ () استفاده می کند. با این حال فقط برای 64bit Linux و Mac در دسترس است.

اگر PySide2 و PyQt5 را هدف قرار می دهید از .exec_ () استفاده کنید


مطالب مرتبط:


شکافها و سیگنال ها

با تعریف اسلات ها و سیگنال های سفارشی از روشی کمی متفاوت بین دو کتابخانه استفاده می شود. PySide2 این رابط را تحت نام های Signal و Slot فراهم می کند در حالی که PyQt5 به ترتیب pyqtSignal و pyqtSlot را فراهم می کند. رفتار هر دو برای تعریف و اسلات ها و سیگنال ها یکسان است.

مثالهای زیر PyQt5 و PySide2 یکسان هستند :

my_custom_signal = pyqtSignal()  # PyQt5
my_custom_signal = Signal()  # PySide2

my_other_signal = pyqtSignal(int)  # PyQt5
my_other_signal = Signal(int)  # PySide2

یا برای شکاف :

@pyqtslot
def my_custom_slot():
    pass

@Slot
def my_custom_slot():
    pass

اگر می خواهید از هماهنگیه  PyQt5 و PySide2 اطمینان حاصل کنید ، می توانید از الگوی واردات زیر برای PyQt5 استفاده کنید تا از سبک سیگنال وSlot نیز در آنجا استفاده کنید.

from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot

البته شما می توانید بر عکس همین روش از PySide2.QtCore سیگنال وارداتی به عنوان pyqtSignal ، اسلات به عنوان pyqtSlot استفاده کنید  گرچه کمی گیج کننده است.

پشتیبانی از هر دو  کتابخانه

اگر در حال نوشتن یک برنامه مستقل نیستید ، لازم نیست نگران این موضوع باشید ، فقط از هر API که ترجیح می دهید استفاده کنید.

اگر شما در حال نوشتن کتابخانه ، ویجت یا ابزار دیگری هستید که می خواهید با PyQt5 و PySide2 سازگار باشید ، می توانید با افزودن هر دو مجموعه واردات ، این کار را به راحتی انجام دهید.

import sys

if 'PyQt5' in sys.modules:
    # PyQt5
    from PyQt5 import QtGui, QtWidgets, QtCore
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot

else:
    # PySide2
    from PySide2 import QtGui, QtWidgets, QtCore
    from PySide2.QtCore import Signal, Slot

این رویکردی است که در کتابخانه ابزارک های سفارشی استفاده می شود ، جایی که ما از PyQt5 و PySide2 با یک واردات کتابخانه پشتیبانی می کنیم. تنهالازم است که شما باید هنگام وارد کردن این کتابخانه اطمینان حاصل کنید که PyQt5 قبل از واردات (مانند خط بالا یا قبل از آن) وارد شده است تا اطمینان حاصل کنید که در sys.modules است.

اگر این کار را در چندین فایل انجام می دهید ، می تواند کمی دست و پا گیر شود. یک راه حل خوب برای این کار انتقال منطق واردات به پرونده خود است ، به عنوان مثال.فایل  qt.py را در ریشه پروژه خود ایجاد کنید. این فایل  ماژول های Qt QtCore ، QtGui ، QtWidgets و غیره را از یکی از دو کتابخانه وارد می کند و سپس از آنجا وارد برنامه خود می شوید.

محتوایه  qt.py همان است که قبلاً از آن استفاده کردیم :

import sys

if 'PyQt5' in sys.modules:
    # PyQt5
    from PyQt5 import QtGui, QtWidgets, QtCore
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot

else:
    # PySide2
    from PySide2 import QtGui, QtWidgets, QtCore
    from PySide2.QtCore import Signal, Slot

شما باید به یاد داشته باشید که هر ماژول PyQt5 دیگری که استفاده می کنید (مرورگر ، چندرسانه ای و غیره) را در هر دو شاخه از بلوک if اضافه کنید. سپس می توانید Qt5 را با برنامه خود وارد کنید :

from .qt import QtGui, QtWidgets, QtCore

... و به صورت یکپارچه در هر کتابخانه کار خواهد کرد.

QtPy

اگر نیاز دارید که فقط پشتیبانی Qt5 را هدف قرار دهید (مانند PyQt4 و PySide v1) نگاهی به  QtPy بیندازید. این یک API استاندارد مانند PySide2 را برای PyQt4 ، PySide ، PyQt5 و PySide2 فراهم می کند. با استفاده از QtPy می توانید با استفاده از متغیر محیط QT_API میتوانید مشخص کنید که  کدام API را بارگیری کنید.

import os
os.environ['QT_API'] = 'pyside2'
from qtpy import QtGui, QtWidgets, QtCore  # imports PySide2.

واقعاً همین است

حرف دیگری برای گفتن نیست - این دو پکیج  بسیار شبیه به هم هستند. با استفاده از نکات بالا ، شما باید در گرفتن مثال یا اسناد از PyQt5 و استفاده از آن برای نوشتن برنامه با PySide2 ، احساس راحتی کنید. اگر در  کد های خود نمونه های از  PyQt5 یا PySide2 که آن را نمیتوانید تغییر ندهید ، پیدا  کردید ، در نظرات بیان کنید  ما پست را بروز میکنیم .ما را در هر چه بهتر شدین این مقاله یاری کنید تا دیگران هم بتوانند به سرعت به نتیجه مورد نظر خود برسند

 

علیرضا

Alireza.kh

نظر شما در مورد این پست چیه؟!