动态 add/remove 根据 QWizardPage 内容的变化从 QWizardPage 完成
Dynamically add/remove Finish from QWizardPage based on change in its content
我正在按照 license wizard(使用 PyQt5
)上的教程尝试学习如何创建非线性向导。但是我似乎陷入了一个问题。
我想要一个带有 QComboBox
的页面,其中所选项目确定包含组合框的当前 QWizardPage
是否是最终页面。
到目前为止页面包含以下内容:
class CalibrationPageSource(QWizardPage):
def __init__(self, parent):
super(CalibrationPageSource, self).__init__(parent)
self.setTitle('Calibration Wizard')
self.setSubTitle('Select the source for the calibration')
layout = QVBoxLayout()
label = QLabel('''
<ul>
<li><b>From calibration file</b>: browse and select an existing YAML calibration file that contains the camera matrix and distortion coefficients (for example from a previous calibration)</li>
<li><b>From image files</b>: browse and select one or more image files with the calibration pattern visible inside each</li>
<li><b>From stream</b> - if the calibration node is connected to an active <b><i>Device node</i></b> you can use its image stream to interactively calibrate your device</li>
</ul>
''')
label.setWordWrap(True)
layout.addWidget(label)
layout_sources = QHBoxLayout()
label_sources = QLabel('Source:')
self.selection_sources = QComboBox()
self.selection_sources.addItem('Calibration file')
self.selection_sources.addItem('Image files')
self.selection_sources.addItem('Stream')
self.selection_sources.currentIndexChanged['QString'].connect(self.source_changed)
self.selection_sources.setCurrentIndex(1)
layout_sources.addWidget(label_sources)
layout_sources.addWidget(self.selection_sources)
layout.addLayout(layout_sources)
self.setLayout(layout)
@pyqtSlot(str)
def source_changed(self, source):
if source == 'Calibration file':
self.setFinalPage(True)
# TODO Add file dialog
else:
self.setFinalPage(False)
# TODO Remove file dialog (if present)
每当 self.selection_sources
的当前项目更改为 Calibration file
时,我想跳过使页面最终化的向导的其余部分。在这种情况下,我想删除 Next
按钮。在所有其他情况下(目前只有两种情况:Image files
和 Stream
)我想让向导正常运行,而不是最后一页。
我尝试实现一个自定义isComplete(...)
,但问题在于选择Next
和Finish
时,选择Calibration file
。我可以忍受禁用 Next
按钮(而不是完全隐藏它),但禁用 Finish
基本上对我来说没有意义。 Next
按钮的存在让我感到非常惊讶。当到达最后一页时,它不是应该完全消失吗?
有什么办法解决这个问题吗?我考虑过遍历 QWizardPage
中的项目并手动 disabling/hiding Next
按钮,但我希望有一种更简单、开箱即用的方法来做到这一点。在当前状态下,Finish
的动态插入正在运行,但是由于 Next
按钮,向导的转换设置不正确。
在您的代码中,您已经使用 QWizardPage.setFinalPage(True)
将完成按钮添加到中间页面。现在下一个按钮仍然存在。删除它的一种方法(不确定这是否是最好的方法)是通过调用 QWizard.removePage()
和 QWizard.nextId()
.
来删除所有后续页面
示例:
from PyQt5.QtWidgets import *
def end_wizard_after_page_two():
# add finish button to wizard
p2.setFinalPage(True)
# remove all over buttons
while True:
id = w.nextId()
if id == -1:
break
w.removePage(id)
app = QApplication([])
# page 1
p1 = QWizardPage()
p1.setTitle('Page 1')
# page 2
p2 = QWizardPage()
p2.setTitle('Page 2')
b = QPushButton('No further pages')
b.clicked.connect(end_wizard_after_page_two)
l = QVBoxLayout(p2)
l.addWidget(b)
# page 3
p3 = QWizardPage()
p3.setTitle('Page 3')
# wizard
w = QWizard()
w.addPage(p1)
w.addPage(p2)
w.addPage(p3)
w.show()
app.exec_()
参见本示例中的方法 end_wizard_after_page_two()
。
如果您想反转效果,则必须反向执行所有操作(再次添加剩余的页面并将 setFinalPage 设置为 False)。
这几乎晚了一年,但我想我弄清楚了问题所在。您对 setFinalPage(True)
的调用只是在您的 QWizardPage
中设置了一个状态标志。它不会自动传播回您的 QWizard
.
只有一种信号会向后传播信息:completeChanged
。这个名字有点误导,但文档似乎表明如果你正确阅读它们,它就会做你想做的事情:
If you reimplement isComplete()
, make sure to emit completeChanged()
whenever the value of isComplete()
changes, to ensure that QWizard
updates the enabled or disabled state of its buttons.
事实上,运行 遇到了同样的问题,我可以通过
解决它
if source == 'Calibration file':
self.setFinalPage(True)
...
else:
self.setFinalPage(False)
...
self.completeChanged.emit()
粗体线是新的。在这两种情况下都需要调用它,并将按钮从 "Next" 切换到 "Finish",然后再返回 select 不同的选项。
我正在按照 license wizard(使用 PyQt5
)上的教程尝试学习如何创建非线性向导。但是我似乎陷入了一个问题。
我想要一个带有 QComboBox
的页面,其中所选项目确定包含组合框的当前 QWizardPage
是否是最终页面。
到目前为止页面包含以下内容:
class CalibrationPageSource(QWizardPage):
def __init__(self, parent):
super(CalibrationPageSource, self).__init__(parent)
self.setTitle('Calibration Wizard')
self.setSubTitle('Select the source for the calibration')
layout = QVBoxLayout()
label = QLabel('''
<ul>
<li><b>From calibration file</b>: browse and select an existing YAML calibration file that contains the camera matrix and distortion coefficients (for example from a previous calibration)</li>
<li><b>From image files</b>: browse and select one or more image files with the calibration pattern visible inside each</li>
<li><b>From stream</b> - if the calibration node is connected to an active <b><i>Device node</i></b> you can use its image stream to interactively calibrate your device</li>
</ul>
''')
label.setWordWrap(True)
layout.addWidget(label)
layout_sources = QHBoxLayout()
label_sources = QLabel('Source:')
self.selection_sources = QComboBox()
self.selection_sources.addItem('Calibration file')
self.selection_sources.addItem('Image files')
self.selection_sources.addItem('Stream')
self.selection_sources.currentIndexChanged['QString'].connect(self.source_changed)
self.selection_sources.setCurrentIndex(1)
layout_sources.addWidget(label_sources)
layout_sources.addWidget(self.selection_sources)
layout.addLayout(layout_sources)
self.setLayout(layout)
@pyqtSlot(str)
def source_changed(self, source):
if source == 'Calibration file':
self.setFinalPage(True)
# TODO Add file dialog
else:
self.setFinalPage(False)
# TODO Remove file dialog (if present)
每当 self.selection_sources
的当前项目更改为 Calibration file
时,我想跳过使页面最终化的向导的其余部分。在这种情况下,我想删除 Next
按钮。在所有其他情况下(目前只有两种情况:Image files
和 Stream
)我想让向导正常运行,而不是最后一页。
我尝试实现一个自定义isComplete(...)
,但问题在于选择Next
和Finish
时,选择Calibration file
。我可以忍受禁用 Next
按钮(而不是完全隐藏它),但禁用 Finish
基本上对我来说没有意义。 Next
按钮的存在让我感到非常惊讶。当到达最后一页时,它不是应该完全消失吗?
有什么办法解决这个问题吗?我考虑过遍历 QWizardPage
中的项目并手动 disabling/hiding Next
按钮,但我希望有一种更简单、开箱即用的方法来做到这一点。在当前状态下,Finish
的动态插入正在运行,但是由于 Next
按钮,向导的转换设置不正确。
在您的代码中,您已经使用 QWizardPage.setFinalPage(True)
将完成按钮添加到中间页面。现在下一个按钮仍然存在。删除它的一种方法(不确定这是否是最好的方法)是通过调用 QWizard.removePage()
和 QWizard.nextId()
.
示例:
from PyQt5.QtWidgets import *
def end_wizard_after_page_two():
# add finish button to wizard
p2.setFinalPage(True)
# remove all over buttons
while True:
id = w.nextId()
if id == -1:
break
w.removePage(id)
app = QApplication([])
# page 1
p1 = QWizardPage()
p1.setTitle('Page 1')
# page 2
p2 = QWizardPage()
p2.setTitle('Page 2')
b = QPushButton('No further pages')
b.clicked.connect(end_wizard_after_page_two)
l = QVBoxLayout(p2)
l.addWidget(b)
# page 3
p3 = QWizardPage()
p3.setTitle('Page 3')
# wizard
w = QWizard()
w.addPage(p1)
w.addPage(p2)
w.addPage(p3)
w.show()
app.exec_()
参见本示例中的方法 end_wizard_after_page_two()
。
如果您想反转效果,则必须反向执行所有操作(再次添加剩余的页面并将 setFinalPage 设置为 False)。
这几乎晚了一年,但我想我弄清楚了问题所在。您对 setFinalPage(True)
的调用只是在您的 QWizardPage
中设置了一个状态标志。它不会自动传播回您的 QWizard
.
只有一种信号会向后传播信息:completeChanged
。这个名字有点误导,但文档似乎表明如果你正确阅读它们,它就会做你想做的事情:
If you reimplement
isComplete()
, make sure to emitcompleteChanged()
whenever the value ofisComplete()
changes, to ensure thatQWizard
updates the enabled or disabled state of its buttons.
事实上,运行 遇到了同样的问题,我可以通过
解决它if source == 'Calibration file': self.setFinalPage(True) ... else: self.setFinalPage(False) ... self.completeChanged.emit()
粗体线是新的。在这两种情况下都需要调用它,并将按钮从 "Next" 切换到 "Finish",然后再返回 select 不同的选项。