Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 根据QWizardPage内容的变化动态添加/删除Finish_Qt_Pyqt_Wizard_Transitions_Pyqt5 - Fatal编程技术网

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

Qt 根据QWizardPage内容的变化动态添加/删除Finish,qt,pyqt,wizard,transitions,pyqt5,Qt,Pyqt,Wizard,Transitions,Pyqt5,我正在学习如何使用PyQt5创建非线性向导的教程。然而,我似乎被困在一个问题上 我希望有一个带有QComboBox的页面,其中所选项目确定包含combobox的当前QWizardPage是否为最终页面 以下是该页面目前包含的内容: class CalibrationPageSource(QWizardPage): def __init__(self, parent): super(CalibrationPageSource, self).__init__(parent)

我正在学习如何使用PyQt5创建非线性向导的教程。然而,我似乎被困在一个问题上

我希望有一个带有QComboBox的页面,其中所选项目确定包含combobox的当前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的当前项目更改为校准文件时,我希望跳过向导的其余部分,使页面成为最终页面。在这种情况下,我想删除下一步按钮。在所有其他情况下,目前只有两个:图像文件和流,我想让向导正常运行,而不是作为最后一页

我已经尝试实现一个自定义的isComplete。。。但问题是,当选择校准文件时,它同时禁用Next和Finish。我可以接受禁用“下一步”按钮而不是完全隐藏它,但禁用“结束”按钮在我的情况下基本上没有意义。我真的很惊讶下一个按钮出现了。当到达最后一页时,它不应该完全消失吗


有没有办法解决这个问题?我曾想过在QWizardPage中迭代这些项目,并手动禁用/隐藏Next按钮,但我希望有一种更简单、现成的方法来做到这一点。在当前状态下,动态插入Finish正在工作,但是由于“下一步”按钮,向导的转换未正确设置。

在代码中,您已经使用QWizardPage.setFinalPageTrue将Finish按钮添加到中间页。现在“下一步”按钮仍然存在。删除它的一种方法不确定这是否是最好的方法是通过调用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_()
请参阅本例第二页后面的方法结束向导


如果你想扭转这种效果,你必须采取一切措施,将剩余的页面再次反向添加,并将FinalPage设置为False。

这几乎晚了一年,但我想我找到了问题所在。调用setFinalPageTrue,只需在QWizardPage中设置一个状态标志。它不会自动传播回QQ向导

只有一个信号会将信息传回:。这个名字有点误导人,但这些文件似乎表明,如果你读得恰到好处,它会达到你的目的:

如果重新实现isComplete,请确保在isComplete值更改时发出completeChanged,以确保QWizard更新其按钮的启用或禁用状态

事实上,在遇到同样的问题后,我能够通过以下方法解决它

if source == 'Calibration file': self.setFinalPage(True) ... else: self.setFinalPage(False) ... self.completeChanged.emit()
粗体线是新的。在这两种情况下都需要调用它,当您选择不同的选项时,它会从“下一步”到“完成”再到“返回”切换按钮。

Nice。它起作用了。我想知道是否有更有效的方法来做这件事。现在我将把它标记为答案。谢谢。我最后不得不发出completeChanged来动态更改QWizardPage::nextId值。