После нажатия кнопки QPushButton выполнить некоторый код и автоматически завершить переход к следующему QWizardPage.

У меня есть мастер с тремя страницами. Первая страница 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_())

1 ответ

Решение

Смена страниц (и кнопка "Далее / Готово" и т. Д.) Обрабатывается 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()
Другие вопросы по тегам