如何使用 PySide2 在 QWizardPage 中加载 Qt Designer 文件 (.ui)

How to load a Qt Designer file (.ui) in a QWizardPage using PySide2

我想在 Qt Designer 中设计我的 QWizardPages,我想用 PySide2 将它们加载到我的 Python 程序中。以前我一直在使用 PyQt5 没有任何问题,但是切换到 PySide2 似乎比预期的要难。 我面临的问题是,当我将 QWizardPage 添加到我的 QWizard 时,该页面确实已添加到向导中,但也添加了另一个(空)页面。我找不到我做错了什么,所以我想知道是否有人可以看看。

我尝试使用函数 addPage() 和 setPage() 添加页面,但它们给出了相同的结果。我还注意到,当我使用 setTitle() 明确设置页面的标题时,空(不需要的)页面会得到这个标题,而不是我在 Qt Designer 中设计的页面。

import os
import sys
from PySide2.QtWidgets import QWizard, QWizardPage, QApplication
from PySide2.QtCore import QFile
from PySide2.QtUiTools import QUiLoader
from enum import Enum


class MyWizard(QWizard):

    def __init__(self):
        super().__init__()

        self.setPage(PageNumbers.page_one.value, PageOne(self))


class PageOne(QWizardPage):

    def __init__(self, parent):
        super().__init__(parent)

        ui_file = os.path.join(__file__, '..', 'pageOne.ui')
        file = QFile(ui_file)
        file.open(QFile.ReadOnly)
        loader = QUiLoader()
        loader.load(file, parent)
        file.close()
        self.setTitle("This is another test Title")


class PageNumbers(Enum):
    page_one = 1


if __name__ == '__main__':

    app = QApplication(sys.argv)

    wizard = MyWizard()
    wizard.show()

    app.exec_()

我希望只显示一个 QWizardPage,并直接显示“完成”按钮。相反,我得到两个 QWizardPages,如下图所示:

谁能告诉我这是怎么回事?

(我使用 PyQt5 和以下代码得到了预期的结果:https://pastebin.com/6W2sx9M1

PyQt 的开发人员实现了能够基于 .ui 创建 classes 的功能,默认情况下在 Qt 中没有实现(Qt/C+ + 使用 MOC 来完成这项工作),但在 PySide2-Qt for python 的情况下它没有实现它,只有 QUiLoader class 允许创建基于在 .ui 上不像 PyQt 允许填充 class.

总之,PySide2 的 loadUi 函数中没有 equivalent,因此您无法实现相同的逻辑。 PySide2 不是 PyQt5,有自己的 equi价,因为它们使用相同的基础,但它们有实现、限制和优势。

进入实际问题,考虑到 .ui 在 .py 旁边,解决方案如下:

import os
import sys
from PySide2 import QtCore, QtWidgets, QtUiTools
from enum import Enum

class PageNumbers(Enum):
    page_one = 0

class MyWizard(QtWidgets.QWizard):
    def __init__(self):
        super().__init__()
        ui_file = os.path.join(os.path.dirname(os.path.abspath(__file__)) ,'PageOne.ui')
        page_one = create_widget(ui_file, self)
        self.setPage(PageNumbers.page_one.value, page_one)

def create_widget(filename, parent=None):
    file = QtCore.QFile(filename)
    if not file.open(QtCore.QFile.ReadOnly):
        return
    loader = QtUiTools.QUiLoader()
    widget = loader.load(file, parent)
    return widget

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    wizard = MyWizard()
    wizard.show()
    sys.exit(app.exec_())