Search code examples
pythonpyqtpyqt5qwizard

How can I unregister fields in python Qwizard?


I have an app using PyQt5 and Qwizard (I can't post the real app because I'm not allowed to) and this is the structure.

I would like that the line edit in page 1 is a mandatory field unless the checkbox is checked.

I tried registering the line edit field, but when I check the checkbox it doesn't let me proceed.

I thought about doing something like if checked then register, but I cant find how to unregister the line edit field.

import sys
from PyQt5.QtWidgets import QWidget, QApplication, QToolBar, QAction, QVBoxLayout, QHBoxLayout, QGridLayout, QLabel,\
    QGroupBox, QWizard, QWizardPage, QPushButton, QLineEdit, QComboBox
import PyQt5.QtGui as QtGui
from PyQt5.QtGui import QFont


class App(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.left = 200
        self.top = 200
        self.width = 640
        self.height = 480
        self.title = "App"
        self.setWindowTitle(self.title)
        self.setWindowIcon(QtGui.QIcon("logo.ico"))
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.toolbar = QToolBar("")

        ########################## ToolbarButtons ###################################
        self.button_add = QAction("Add", self)
        self.button_add.setIcon(QtGui.QIcon("add.ico"))
        self.button_add.setStatusTip("Add stuff")
        self.toolbar.addAction(self.button_add)
        self.button_browse = QAction("Open", self)
        self.button_browse.setIcon(QtGui.QIcon("folder.ico"))
        self.button_browse.setStatusTip("Open stuff")
        self.toolbar.addAction(self.button_browse)
        self.button_save = QAction("Save", self)
        self.button_save.setIcon(QtGui.QIcon("save.ico"))
        self.button_save.setStatusTip("Save stuff")
        self.toolbar.addAction(self.button_save)
        self.button_settings = QAction("Settings", self)
        self.button_settings.setIcon(QtGui.QIcon("settings.ico"))
        self.button_settings.setStatusTip("Set stuff")
        self.toolbar.addAction(self.button_settings)


        self.window_layout = QGridLayout()
        self.setLayout(self.window_layout)
        self.wizard = WizardInit()
        print("Test")
        self.wizard.setWizardStyle(QWizard.ModernStyle)
        self.show()
        self.wizard.show()


class WizardInit(QWizard):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Wizard")
        self.resize(500, 500)
        self.addPage(Page1())


class Page1(QWizardPage):
    def __init__(self):
        super().__init__()
        self.line_edit = QLineEdit()
        self.registerField("Test*", self.line_edit)
        self.check_box = QCheckBox("test_checkbox")
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

Solution

  • Unfortunately it is not possible to unregister the fields.

    A possible solution is to override the isComplete method that determines whether the "Next" or "Finish" button are enabled or not, and to update it, the completeChanged signal must be emitted.

    import sys
    from PyQt5 import QtWidgets
    
    
    class Wizard(QtWidgets.QWizard):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Wizard")
            self.resize(500, 500)
            self.addPage(Page1())
    
    
    class Page1(QtWidgets.QWizardPage):
        def __init__(self):
            super().__init__()
            self.line_edit = QtWidgets.QLineEdit()
            self.check_box = QtWidgets.QCheckBox("test_checkbox")
    
            lay = QtWidgets.QVBoxLayout(self)
            lay.addWidget(self.line_edit)
            lay.addWidget(self.check_box)
    
            self.registerField("Test*", self.line_edit)
            self.check_box.toggled.connect(self.completeChanged)
    
        def isComplete(self):
            if self.check_box.isChecked():
                return True
            return super().isComplete()
    
    
    if __name__ == "__main__":
        app = QtWidgets.QApplication(sys.argv)
        w = Wizard()
        w.show()
        sys.exit(app.exec_())