0

我有一个三页的向导。第一页是BasicSettings(),第二页是InstallPackages(),最后一页(完成)是Summary()BasicSettings()用于创建虚拟环境。如果未选中“安装和更新 Pip”复选框,向导应该直接转到最后一页Summary(),否则它应该转到InstallPackages()用户可以将一些软件包安装到创建的虚拟环境中的位置。最后一步是从那里到Summary()有“完成”按钮的地方。

在下面的代码示例中,createButton连接到方法execute_venv_create()。当该方法执行完代码后,会弹出一个消息框,指示该过程已完成。

现在,当用户单击时,Ok我希望向导自动转到由QWizard().nextId. 我认为我可以通过调用来实现这一点QWizard().next(),但这不起作用。我尝试连接createButton到它,但这没有效果。

execute_venv_create()执行完代码并且用户确认信息框后,如何使向导自动进入下一页?


重现代码:

# -*- coding: utf-8 -*-
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QApplication, QGridLayout, QLabel, QCheckBox,
                             QHBoxLayout, QVBoxLayout, QToolButton, QWizard,
                             QWizardPage, QComboBox, QTableView, QLineEdit,
                             QGroupBox, QPushButton, QMessageBox)


class VenvWizard(QWizard):
    """
    Wizard for creating and setting up a virtual environment.
    """
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Venv Wizard")
        self.resize(635, 480)
        self.move(528, 153)

        basicSettings = BasicSettings()
        self.addPage(basicSettings)

        installId = self.addPage(InstallPackages())
        summaryId = self.addPage(Summary())

        # go to last page if pip wasn't selected else go to the install page
        basicSettings.nextId = (
            lambda: installId if basicSettings.withPipCBox.isChecked()
            else summaryId
        )

        # ...

class BasicSettings(QWizardPage):
    """
    Basic settings of the virtual environment to create.
    """
    def __init__(self):
        super().__init__()

        folder_icon = QIcon.fromTheme("folder")

        self.setTitle("Basic Settings")
        self.setSubTitle("..........................."
                         "...........................")

        interpreterLabel = QLabel("&Interpreter:")
        self.interprComboBox = QComboBox()
        interpreterLabel.setBuddy(self.interprComboBox)

        venvNameLabel = QLabel("Venv &name:")
        self.venvNameLineEdit = QLineEdit()
        venvNameLabel.setBuddy(self.venvNameLineEdit)

        venvLocationLabel = QLabel("&Location:")
        self.venvLocationLineEdit = QLineEdit()
        venvLocationLabel.setBuddy(self.venvLocationLineEdit)

        self.selectDirToolButton = QToolButton(icon=folder_icon)
        self.selectDirToolButton.setFixedSize(26, 27)

        placeHolder = QLabel()

        # options groupbox
        groupBox = QGroupBox("Options")

        self.withPipCBox = QCheckBox(
            "Install and update &Pip"
        )
        self.sitePackagesCBox = QCheckBox(
            "&Make system (global) site-packages dir available to venv"
        )
        self.symlinksCBox = QCheckBox(
            "Attempt to &symlink rather than copy files into venv"
        )
        self.launchVenvCBox = QCheckBox(
            "Launch a &terminal with activated venv after installation"
        )
        self.createButton = QPushButton(
            "&Create", self,
            clicked=self.execute_venv_create,
        )
        self.createButton.setFixedWidth(90)

        # box layout containing the create button
        h_BoxLayout = QHBoxLayout()
        h_BoxLayout.setContentsMargins(495, 5, 0, 0)
        h_BoxLayout.addWidget(self.createButton)

        # grid layout
        gridLayout = QGridLayout()
        gridLayout.addWidget(interpreterLabel, 0, 0, 1, 1)
        gridLayout.addWidget(self.interprComboBox, 0, 1, 1, 2)
        gridLayout.addWidget(venvNameLabel, 1, 0, 1, 1)
        gridLayout.addWidget(self.venvNameLineEdit, 1, 1, 1, 2)
        gridLayout.addWidget(venvLocationLabel, 2, 0, 1, 1)
        gridLayout.addWidget(self.venvLocationLineEdit, 2, 1, 1, 1)
        gridLayout.addWidget(self.selectDirToolButton, 2, 2, 1, 1)
        gridLayout.addWidget(placeHolder, 3, 0, 1, 2)
        gridLayout.addWidget(groupBox, 4, 0, 1, 3)
        gridLayout.addLayout(h_BoxLayout, 5, 0, 1, 0)
        self.setLayout(gridLayout)

        # options groupbox
        groupBoxLayout = QVBoxLayout()
        groupBoxLayout.addWidget(self.withPipCBox)
        groupBoxLayout.addWidget(self.sitePackagesCBox)
        groupBoxLayout.addWidget(self.symlinksCBox)
        groupBoxLayout.addWidget(self.launchVenvCBox)
        groupBox.setLayout(groupBoxLayout)

    def execute_venv_create(self):
        """
        Execute the creation process.
        """
        # do something, then display info message
        QMessageBox.information(self, "Done", "message text")
        # when user clicks 'Ok', go to the next page defined in .nextId


class InstallPackages(QWizardPage):
    """
    Install packages via `pip` into the created virtual environment.
    """
    def __init__(self):
        super().__init__()

        self.setTitle("Install Packages")
        self.setSubTitle("..........................."
                         "...........................")

        verticalLayout = QVBoxLayout()
        gridLayout = QGridLayout(self)

        pkgNameLabel = QLabel("Package name:")
        self.pkgNameLineEdit = QLineEdit()
        self.searchButton = QPushButton("Search")
        resultsTable = QTableView(self)

        gridLayout.addWidget(pkgNameLabel, 0, 0, 1, 1)
        gridLayout.addWidget(self.pkgNameLineEdit, 0, 1, 1, 1)
        gridLayout.addWidget(self.searchButton, 0, 2, 1, 1)
        gridLayout.addWidget(resultsTable, 1, 0, 1, 3)

        verticalLayout.addLayout(gridLayout)

        # ...

class Summary(QWizardPage):
    def __init__(self):
        super().__init__()

        self.setTitle("Summary")
        self.setSubTitle("..........................."
                         "...........................")

        # ...

    def initializePage(self):
        pass


if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    wiz = VenvWizard()
    wiz.exec_()

    sys.exit(app.exec_())
4

1 回答 1

2

页面的更改(以及下一步/完成按钮等)由QWizard页面而不是页面本身处理。

由于您无法从QWizard中调用方法QWizardPage,因此无需单击下一步按钮即可更改页面的最简单方法是使用信号:

class VenvWizard(QWizard):
    """
    Wizard for creating and setting up a virtual environment.
    """
        def __init__(self):
        super().__init__()

        self.setWindowTitle("Venv Wizard")
        self.resize(635, 480)
        self.move(528, 153)

        self.basicSettings = BasicSettings()
        self.basicSettingsId = self.addPage(self.basicSettings)

        self.installId = self.addPage(InstallPackages())
        self.summaryId = self.addPage(Summary())


        self.basicSettings.done.connect(self.next)

        # go to last page if pip wasn't selected else go to the install page

    def nextId(self):
        # Process the flow only if the current page is basic settings
        if self.currentId() != self.basicSettingsId:
            return super().nextId()

        if self.basicSettings.withPipCBox.isChecked():
            return self.installId
        else:
            return self.summaryId
    done = pyqtSignal()
    def execute_venv_create(self):
        """
        Execute the creation process.
        """
        # do something, then display info message
        ok = QMessageBox.information(self, "Done", "message text")
        # when user clicks 'Ok', go to the next page defined in .nextId
        self.done.emit()
于 2019-08-03T11:37:32.497 回答