Пропустить следующую QWizardPage в зависимости от QCheckBox.isChecked() со страницы до
Я работаю над мастером для установки загруженных пакетов. В определенный момент я хочу пропустить следующий QWizardPage
в зависимости от того, установлен ли флажок на странице ранее или нет.
Страница, которую я хочу пропустить, является InstallPackages
класс и случай, когда он должен быть пропущен, если флажок self.withPipCBox
не проверяется.
Я знаю, что я должен использовать QCheckBox.isChecked()
для этого, но как его использовать?
Код:
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt, QObject, QTimer, QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import (QApplication, QFileDialog, QGridLayout, QLabel,
QVBoxLayout, QWizard, QWizardPage, QProgressBar,
QCheckBox, QLineEdit, QGroupBox, QToolButton,
QComboBox, QDialog, QHBoxLayout)
class VenvWizard(QWizard):
"""
Wizard for creating and setting up virtual environments.
"""
def __init__(self):
super().__init__()
self.setWindowTitle("Venv Wizard")
self.resize(535, 430)
self.move(578, 183)
self.setStyleSheet(
"""
QToolTip {
background-color: rgb(47, 52, 63);
border: rgb(47, 52, 63);
color: rgb(210, 210, 210);
padding: 2px;
opacity: 325
}
"""
)
self.addPage(BasicSettings())
self.addPage(InstallPackages())
self.addPage(Summary())
class BasicSettings(QWizardPage):
"""
Basic settings of the virtual environment being created.
"""
def __init__(self):
super().__init__()
folder_icon = QIcon.fromTheme("folder")
self.setTitle("Basic Settings")
self.setSubTitle("This wizard will help you to create and set up "
"a virtual environment for Python 3. ")
interpreterLabel = QLabel("&Interpreter:")
self.interprComboBox = QComboBox()
interpreterLabel.setBuddy(self.interprComboBox)
self.interprComboBox.addItem("---")
venvNameLabel = QLabel("Venv &name:")
self.venvNameLineEdit = QLineEdit()
venvNameLabel.setBuddy(self.venvNameLineEdit)
venvLocationLabel = QLabel("&Location:")
self.venvLocationLineEdit = QLineEdit()
venvLocationLabel.setBuddy(self.venvLocationLineEdit)
selectFolderToolButton = QToolButton()
selectFolderToolButton.setFixedSize(26, 27)
selectFolderToolButton.setIcon(folder_icon)
selectFolderToolButton.setToolTip("Browse")
placeHolder = QLabel()
# the '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")
# 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(selectFolderToolButton, 2, 2, 1, 1)
gridLayout.addWidget(placeHolder, 3, 0, 1, 2)
gridLayout.addWidget(groupBox, 4, 0, 1, 3)
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)
class InstallPackages(QWizardPage):
"""
Install packages via `pip` into the created virtual environment.
"""
def __init__(self):
super().__init__()
self.setTitle("Install Packages")
self.setSubTitle("Specify the packages which you want Pip to "
"install into the virtual environment.")
# just some content for testing
TestLabel = QLabel("This is a test label:", self)
TestLineEdit = QLineEdit(self)
TestLabel.setBuddy(TestLineEdit)
TestLabel2 = QLabel("This is a test label:", self)
TestLineEdit2 = QLineEdit(self)
TestLabel2.setBuddy(TestLineEdit2)
v_layout = QVBoxLayout(self)
v_layout.addWidget(TestLabel)
v_layout.addWidget(TestLineEdit)
v_layout.addWidget(TestLabel2)
v_layout.addWidget(TestLineEdit2)
self.setLayout(v_layout)
def initializePage(self):
pass
class Summary(QWizardPage):
def __init__(self):
super().__init__()
self.setTitle("Summary")
self.setSubTitle("...............")
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
wizard = VenvWizard()
wizard.show()
sys.exit(app.exec_())
1 ответ
Вам необходимо реализовать nextId()
страницы мастера или самого мастера (который по умолчанию вызывает currentPage().nextId()
).
В первом случае вам нужно сохранить или получить ссылку на две страницы, но это также можно сделать, переопределив nextId()
экземпляра: это виртуальная функция, что означает, что она может быть переопределена в экземпляре из самого мастера, что позволяет вам немного упростить вещи, так как у вас есть доступ к pageId
как только вы добавите их:
basicSettings = BasicSettings()
self.addPage(basicSettings)
installId = self.addPage(InstallPackages())
summaryId = self.addPage(Summary())
basicSettings.nextId = lambda: installId if basicSettings.interprComboBox.isChecked() else summaryId
Вы можете сделать почти то же самое в nextId()
переопределение мастера, пока вы сохраняете ссылку на страницу, которая содержит хотя бы флажок.
Вот немного другой подход к методу, показанному выше:
class VenvWizard(QWizard):
def __init__(self):
super().__init__()
[...]
self.basicSettings = BasicSettings()
self.addPage(self.basicSettings)
[...]
def nextId(self):
if self.currentPage() == self.basicSettings:
# since python bools can behave as integers, you can add
# 0 or 1 to the pageId using the isChecked() result
return self.currentId() + 1 + self.basicSettins.interprComboBox.isChecked()
# if you need the opposite (skip if unchecked) use this instead
#return self.currentId() + 1 + (not self.basicSettins.interprComboBox.isChecked())
return QtWidgets.QWizard.nextId(self)
Кстати, приведенный выше пример будет работать только для непрерывных номеров идентификаторов, что означает, что он не будет работать должным образом, если вы используете "нелинейные" идентификаторы с setPage(id, page)
вместо основного addPage(page)
(то же самое происходит, если вы хотите пропустить более одной страницы, очевидно); в этом случае вам понадобится ссылка на два идентификатора страницы:
class VenvWizard(QWizard):
def __init__(self):
super().__init__()
[...]
self.basicSettings = BasicSettings()
self.addPage(self.basicSettings)
self.installId = self.addPage(InstallPackages())
self.summaryId = 20
self.setPage(self.summaryId, Summary())
def nextId(self):
if self.currentPage() == self.basicSettings:
if self.basicSettins.interprComboBox.isChecked():
return self.installId
return self.summaryId
return QtWidgets.QWizard.nextId(self)
PS: пожалуйста, постарайтесь, чтобы примеры были как можно меньше. На самом деле нет необходимости публиковать все, что содержит ваш код: раздражает только различие между кодом, который имеет смысл или бесполезен для вопроса, и отговаривает людей, желающих помочь, даже пытаться проверить ваш код.