单击 QPushButton 后执行一些代码,完成后自动转到下一个 QWizardPage
After QPushButton clicked execute some code and when finished automatically go to next QWizardPage
我有一个包含三个页面的向导。第一页是 BasicSettings()
,第二页是 InstallPackages()
,最后一页(完成)是 Summary()
。 BasicSettings()
用于创建虚拟环境。如果未选中 'Install and update Pip' 复选框,向导应该直接转到最后一页 Summary()
,否则它应该继续到 InstallPackages()
用户可以将一些包安装到创建的虚拟环境中。最后一步是从那里转到 Summary()
那里有 'finish' 按钮。
在下面的代码示例中,createButton
连接到方法 execute_venv_create()
。当该方法执行完代码时,会弹出一个消息框,指示该过程已完成。
现在,当用户单击 确定时 我希望向导自动转到 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_())
页面(和按钮 next/finish 等)的更改由 QWizard
而不是页面本身处理。
由于您无法在 QWizardPage
中调用 QWizard
的方法,因此无需单击 下一步 按钮即可更改页面的最简单方法是使用信号:
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()
我有一个包含三个页面的向导。第一页是 BasicSettings()
,第二页是 InstallPackages()
,最后一页(完成)是 Summary()
。 BasicSettings()
用于创建虚拟环境。如果未选中 'Install and update Pip' 复选框,向导应该直接转到最后一页 Summary()
,否则它应该继续到 InstallPackages()
用户可以将一些包安装到创建的虚拟环境中。最后一步是从那里转到 Summary()
那里有 'finish' 按钮。
在下面的代码示例中,createButton
连接到方法 execute_venv_create()
。当该方法执行完代码时,会弹出一个消息框,指示该过程已完成。
现在,当用户单击 确定时 我希望向导自动转到 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_())
页面(和按钮 next/finish 等)的更改由 QWizard
而不是页面本身处理。
由于您无法在 QWizardPage
中调用 QWizard
的方法,因此无需单击 下一步 按钮即可更改页面的最简单方法是使用信号:
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()