根据前一页的 QCheckBox.isChecked() 跳过下一个 QWizardPage
Skip the next QWizardPage depending on QCheckBox.isChecked() from the page before
我正在开发用于安装下载包的向导。在某个特定点,我想跳过下一个 QWizardPage
,具体取决于之前页面上的复选框是否被选中。
我要跳过的页面是 InstallPackages
class 应该跳过的情况是复选框 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_())
您需要实现向导页面的 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)
顺便说一句,上面的示例仅适用于连续的 ID 号,这意味着如果您将 "non linear" ID 与 setPage(id, page)
一起使用而不是基本的 addPage(page)
,它将无法正常运行(显然,如果您想跳过一页以上,也是如此);如果是这样,您需要引用两个页面 ID:
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:请尽量减少示例。真的没有必要post 你的代码包含的所有东西:区分对问题有意义或无用的代码只会让人很烦人,阻止人们愿意提供帮助甚至尝试检查您的代码。
我正在开发用于安装下载包的向导。在某个特定点,我想跳过下一个 QWizardPage
,具体取决于之前页面上的复选框是否被选中。
我要跳过的页面是 InstallPackages
class 应该跳过的情况是复选框 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_())
您需要实现向导页面的 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)
顺便说一句,上面的示例仅适用于连续的 ID 号,这意味着如果您将 "non linear" ID 与 setPage(id, page)
一起使用而不是基本的 addPage(page)
,它将无法正常运行(显然,如果您想跳过一页以上,也是如此);如果是这样,您需要引用两个页面 ID:
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:请尽量减少示例。真的没有必要post 你的代码包含的所有东西:区分对问题有意义或无用的代码只会让人很烦人,阻止人们愿意提供帮助甚至尝试检查您的代码。