Search code examples
qtsignals-slotsqwizardqwizardpage

QWizardPage: how to re-disable "Next" button


I have a QWizardPage where user is supposed to go through certain steps, at the end of which there is a button "Test". If user presses that button, two things happen:

  1. "Next" button gets enabled in order to go to the next page of the QWizard. This is achieved by emitting a button's special signal which is connected to QWizardPage:

    this->registerField("test*", m_button, "text", SIGNAL(testDone()));

m_button is derived from QPushButton with a custom signal testDone().

  1. Button name is changed to "Try again" in order to offer an option to try the series of steps all over again. If user presses the button, the GUI elements return to the initial state (except disabling the button "Next" on QWizard).

The question is: for the second scenario, how do I make sure the "Next" button gets disabled after being enabled by the emitted testDone() signal?

I thought if I disconnect the particular signal testDone() from QwizardPage (after it is emitted), it would give the desired results, however, it did not work. I tried to disconnect everything on the QWizardPage (e.g. this->disconnect), but that also didn't work. Any other ideas?


Solution

  • To control the pages "readyness", you typically override QWizardPage::isComplete and signal changes via QWizardPage::completeChanged.

    So for your example, you could give your button a property and connect it accordingly:

    class MyButton : public QPushButton
    {
        Q_OBJECT
    
        Q_PROPERTY(bool ready READ isReady NOTIFY readyChanged)
    
    public:
        MyButton(QWidget *parent);
        bool isReady() const;
    
    signals:
        void readyChanged();
    };
    

    Whenever the button is pressed or the tests completed, emit the signal, and return the desired button state from the isReady function.

    In your wizard page, override isComplete as:

    bool isComplete() const {
        return QWizardPage::isComplete() && myButton->isReady();
    }
    

    and connect the signals in your page:

    connect(myButton, &MyButton::readyChanged, this, &MyPage::completeChanged);