您尚未登录。

楼主 #1 2020-02-21 21:46:47

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

离线

楼主 #2 2020-02-21 21:48:20

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

PySide2 ---- 之所以称为PySide,是因为“ side”是芬兰语中的“ binder”, 也就是"绑定"

离线

楼主 #3 2020-02-21 21:49:16

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

这两个软件包都包装了相同的库Qt5,因此具有99.9%相同的API(请参见下面的一些区别)。为一个编写的代码通常可以与其他代码原样使用,只需将导入从更改为PyQt5即可PySide2。您从一个库中学到的任何内容都可以轻松地应用到另一个库中的项目。

离线

楼主 #4 2020-02-21 22:06:45

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

另外,无论您选择使用哪种,都应该熟悉另一种,因此您可以充分利用所有可用的在线资源,例如使用PyQt5教程来构建PySide2应用程序,反之亦然。

离线

楼主 #6 2020-02-21 22:17:58

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

UI files
Both packages use slightly different approaches for loading .ui files exported from Qt Creator/Designer. PyQt5 provides the uic submodule which can be used to load UI files directly, to produce an object. This feels pretty Pythonic (if you ignore the camelCase).

import sys
from PyQt5 import QtWidgets, uic

app = QtWidgets.QApplication(sys.argv)

window = uic.loadUi("mainwindow.ui")
window.show()
app.exec()
The equivalent with PySide2 is one line longer, since you need to create a QUILoader object first. Unfortunately the api of these two interfaces is different too (.load vs .loadUI) and take different parameters.

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_()
To load a UI onto an object in PyQt5, for example in your QMainWindow.__init__, you can call uic.loadUI passing in self (the target widget) as the second parameter.

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_()
The PySide2 loader does not support this — the second parameter to .load is the parent widget of the widget you're creating. This prevents you adding custom code to the __init__ block of the widget, but you can work around this with a separate function.

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()
Converting UI files to Python
Both libraries provide identical scripts to generate Python importable modules from Qt Designer .ui files. For PyQt5 the script is named pyuic5 —

pyuic5 mainwindow.ui -o MainWindow.py
You can then import the UI_MainWindow object, subclass using multiple inheritance from the base class you're using (e.g. QMainWIndow) and then call self.setupUI(self) to set the UI up.

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()
For PySide2 it is named pyside2-uic —

pyside2-uic mainwindow.ui -o MainWindow.py
The subsequent setup is identical.

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_()
For more information on using Qt Designer with either PyQt5 or PySide2 see the Qt Creator tutorial.

PyQt5 与 PySide2 加载 .ui 界面文件的差异.

离线

楼主 #7 2020-02-21 22:23:31

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

Supporting both in libraries
You don't need to worry about this if you're writing a standalone app, just use whichever API you prefer.

If you're writing a library, widget or other tool you want to be compatible with both PyQt5 and PySide2 you can do so easily by adding both sets of imports.

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

测试了一下:

import sys

if 'PySide' in sys.modules:
    # PySide2
    print("import PySide2")
    from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PySide2.QtCore import Signal, Slot
else:
    # PyQt5
    print("import PyQt5")
    from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot

if __name__ == '__main__':
    app = QApplication(sys.argv)
    mainwindow1 = QDialog()
    label = QLabel("显示测试")
    button = QPushButton("请点击我噢")
    boxlayout1 = QVBoxLayout()
    boxlayout1.addWidget(label)
    boxlayout1.addWidget(button)
    mainwindow1.setLayout(boxlayout1)
    mainwindow1.show()
    mainwindow1.setWindowTitle("测试标题")
    mainwindow1.resize(80, 150)

    sys.exit(app.exec_())

完全没有问题,随心所欲, 喜欢import哪个库都可以了.

离线

楼主 #8 2020-02-21 22:37:34

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

import sys, os

#os.environ["QT_BINDING"] = "PyQt5"
os.environ["QT_BINDING"] = "PySide2"

if os.environ["QT_BINDING"] == "PyQt5": ###'PyQt5.Widgets' in sys.modules:
    print("import PyQt5")
    from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot
    from PyQt5 import uic
elif os.environ["QT_BINDING"] == "PySide2":
    print("import PySide2")
    from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PySide2.QtCore import Signal, Slot
    from PySide2.QtUiTools import QUiLoader


if __name__ == '__main__':
    app = QApplication(sys.argv)

    if os.environ["QT_BINDING"] == "PyQt5":
        window = uic.loadUi("mainwindow.ui")
    elif os.environ["QT_BINDING"] == "PySide2":
        uiloader = QUiLoader()
        window = uiloader.load("mainwindow.ui")

    window.show()

    sys.exit(app.exec_())

现学现用, 通过设置环境变量 QT_BINDING 来决定import PySide2, 还是 import PyQt5

离线

楼主 #9 2020-02-21 23:00:41

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

import sys, os

#os.environ["QT_BINDING"] = "PyQt5"
os.environ["QT_BINDING"] = "PySide2"

if os.environ["QT_BINDING"] == "PyQt5": ###'PyQt5.Widgets' in sys.modules:
    print("import PyQt5")
    from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot, QTimer
    from PyQt5 import uic
elif os.environ["QT_BINDING"] == "PySide2":
    print("import PySide2")
    from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PySide2.QtCore import Signal, Slot, QTimer
    from PySide2.QtUiTools import QUiLoader


@Slot()
def SlotTimeOut():
    print("超时 timout")


if __name__ == '__main__':
    app = QApplication(sys.argv)

    if os.environ["QT_BINDING"] == "PyQt5":
        window = uic.loadUi("mainwindow.ui")
    elif os.environ["QT_BINDING"] == "PySide2":
        uiloader = QUiLoader()
        window = uiloader.load("mainwindow.ui")

    a = 0
    timer1 = QTimer()
    timer1.timeout.connect(SlotTimeOut)
    timer1.start(1000)
    window.show()

    sys.exit(app.exec_())

添加了一个槽函数, PyQt5/PySide2 测试均 OK

参考: https://whycan.cn/t_3729.html

离线

楼主 #10 2020-02-21 23:03:51

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

import sys, os

os.environ["QT_BINDING"] = "PyQt5"
# os.environ["QT_BINDING"] = "PySide2"

if os.environ["QT_BINDING"] == "PyQt5": ###'PyQt5.Widgets' in sys.modules:
    print("import PyQt5")
    from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot, QTimer
    from PyQt5 import uic
elif os.environ["QT_BINDING"] == "PySide2":
    print("import PySide2")
    from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PySide2.QtCore import Signal, Slot, QTimer
    from PySide2.QtUiTools import QUiLoader


@Slot(int)
def SlotTimeOut(i):
    print("定时器" + str(i) + "超时 timout: ")


if __name__ == '__main__':
    app = QApplication(sys.argv)

    if os.environ["QT_BINDING"] == "PyQt5":
        window = uic.loadUi("mainwindow.ui")
    elif os.environ["QT_BINDING"] == "PySide2":
        uiloader = QUiLoader()
        window = uiloader.load("mainwindow.ui")

    a = 0
    timer1 = QTimer()
    timer1.timeout.connect(lambda: SlotTimeOut(1))
    timer1.start(1000)

    timer2 = QTimer()
    timer2.timeout.connect(lambda: SlotTimeOut(2))
    timer2.start(3005)

    window.show()

    sys.exit(app.exec_())

槽函数加了一个签名, 用了 lambda 表达式.


输出:

import PyQt5
定时器1超时 timout: 
定时器1超时 timout: 
定时器1超时 timout: 
定时器2超时 timout: 
定时器1超时 timout: 
定时器1超时 timout: 
定时器1超时 timout: 
定时器2超时 timout: 
定时器1超时 timout: 

离线

楼主 #11 2020-02-21 23:28:12

pythinker
会员
注册时间: 2019-02-12
已发帖子: 215
积分: 215

Re: PyQt5与PySide2:两个Python Qt库之间有什么区别? (转载)

import sys, os

os.environ["QT_BINDING"] = "PyQt5"
# os.environ["QT_BINDING"] = "PySide2"

if os.environ["QT_BINDING"] == "PyQt5": ###'PyQt5.Widgets' in sys.modules:
    print("import PyQt5")
    from PyQt5.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PyQt5.QtCore import pyqtSignal as Signal, pyqtSlot as Slot, QTimer
    from PyQt5 import uic
elif os.environ["QT_BINDING"] == "PySide2":
    print("import PySide2")
    from PySide2.QtWidgets import QApplication, QLabel, QPushButton, QMainWindow, QVBoxLayout, QDialog
    from PySide2.QtCore import Signal, Slot, QTimer
    from PySide2.QtUiTools import QUiLoader


@Slot(int)
def SlotTimeOut(i):
    print("定时器" + str(i) + "超时 timout: ")

@Slot(bool)
def SlotDelButtonClicked(checked):
    print("按钮被选中? " + str(checked))

if __name__ == '__main__':
    app = QApplication(sys.argv)

    if os.environ["QT_BINDING"] == "PyQt5":
        window = uic.loadUi("mainwindow.ui")
    elif os.environ["QT_BINDING"] == "PySide2":
        uiloader = QUiLoader()
        window = uiloader.load("mainwindow.ui")

    a = 0
    timer1 = QTimer()
    timer1.timeout.connect(lambda: SlotTimeOut(1))
    timer1.start(1000)

    timer2 = QTimer()
    timer2.timeout.connect(lambda: SlotTimeOut(2))
    timer2.start(3005)

    window.startStopButton.clicked.connect(lambda: SlotTimeOut(3))

    window.DelPointButton.setCheckable(True)
#    window.DelPointButton.setChecked(True)
    window.DelPointButton.clicked.connect(SlotDelButtonClicked)
    window.show()

    sys.exit(app.exec_())

再添加一个按钮点击的槽函数.

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn