根据内容的变化从 QWizardPage 动态添加/删除 Finish

rba*_*dar 3 qt pyqt wizard transitions pyqt5

我正在学习关于许可向导(使用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)
Run Code Online (Sandbox Code Playgroud)

每当self.selection_sources的当前项目更改为Calibration file我想跳过使页面最终确定的向导的其余部分。在这种情况下,我想删除Next按钮。在所有其他情况下(目前只有两个:Image filesStream),我想让向导正常运行,而不是作为最后一页。

我试图实现自定义的isComplete(...),但问题是,它同时禁用NextFinishCalibration file被选中。我可以忍受有一个禁用Next按钮(而不是完全隐藏它),但Finish在我的情况下禁用基本上没有意义。我真的很惊讶Next按钮的存在。当到达最后一页时,它不应该完全消失吗?

任何想法如何解决这个问题?我考虑过遍历 中的项目QWizardPage并手动禁用/隐藏Next按钮,但我希​​望有一种更简单、开箱即用的方法来做到这一点。在当前状态下,动态插入Finish正在工作,但是由于Next按钮,向导的转换没有正确设置。

Mad*_*ist 6

This is almost a year late, but I think I figured out what the problem is. Your call to setFinalPage(True), just sets a state flag in your QWizardPage. It does not automatically propagate back to your QWizard.

There is only one signal that does propagate information back: completeChanged. The name is slightly misleading, but the docs seem to indicate that it does what you want if you read them just right:

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.

In fact, having run into the same problem, I was able to fix it by doing

if source == 'Calibration file':
    self.setFinalPage(True)
    ...
else:
    self.setFinalPage(False)
    ...
self.completeChanged.emit()

The bolded line is new. It needs to be called in both cases and will toggle the button from "Next" to "Finish" and back as you select different options.

  • 我最终不得不发出“completeChanged()”来动态更改“QWizardPage::nextId()”值。 (2认同)