[QWizard] How to disable the Next button in a wizard until a certain condition is met



  • Hi all
    I was wondering how i would disable the Next button in a wizard page until i have set only four checkboxes checked or clicked them among a bunch of other checkboxes in the wizard page?


  • Moderators

    1.When ever the checkboxes are clicked, check the state of all checkboxes

    1. Get the pointer to "Next" button using wizard->button(WizardButton which) and then use setEnabled(bool) as per the requirement

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    You might be interested by re-implementing "QWizardPage::isComplete":http://qt-project.org/doc/qt-4.8/qwizardpage.html#isComplete

    Hope it helps


  • Moderators

    Or subclass QWizardPage and reimplement isCompleted.



  • Thank you all for replying.
    So i did this:

    @
    connect(checkmeCheckBox, SIGNAL(stateChanged(), QWizard::NextButton, SLOT(nextId())));
    ...
    ...
    ...
    //for all the checkboxes

    int myclass::nextId()
    {
    //then i got stuck here since you can't evaluate the logic for all the four checkboxes since there are like a total of 10 of them and i want to select any four from the 10??
    }
    @



  • Hey
    Is there no actual help in this forum, where did everyone go??
    I've been waiting for like 4 hours!!!! ):


  • Lifetime Qt Champion

    Please, wait at least 24 to 72 hours before bumping your own thread. Most people answering here do it on their free time. Also not everybody lives in the same timezone as you.

    If you're in need of rapid support you can contact Digia/KDAB/ICS etc...


  • Moderators

    Mate, there is no magic automated solution here. This is custom behaviour and you need to sit down, think about it and implement the code.

    Regardless of how many checkboxes you have, be it 10 or a hundred, you need to go through them all and count how many are checked.


  • Moderators

    pkjag,
    Once you subclass QWizardPage, you will get access to the "Next" button using the wizard()->button(QWizard::NextButton). When you check any checkbox, call a common slot and check there the status of all the checkboxes and depending upon your condition call set the "Next" button state using @wizard()->button(QWizard::NextButton)->setEnabled(true)@ or @wizard()->button(QWizard::NextButton)->setEnabled(false)@



  • So i did this:
    @
    connect(checkmeCheckBox, SIGNAL(toggled()),wizard1->button(QWizard::NextButton), SLOT(reactToToggle()));
    ...
    ...
    ...
    //for all the checkboxes in myPage

    int myPage::reactToToggle(bool checked)
    {
    static int i = 0;
    if(checked)
    ++i;
    return i;
    }

    void myPage::returns(bool checked)
    {
    if(reactToToggle(checked)== 3)
    wizard1->button(QWizard::NextButton)->setEnabled(true);
    else
    wizard1->button(QWizard::NextButton)->setDisabled(true);
    }
    @
    but the compiler returns a SIGSEGV error, is there anything wrong with my implementation apart from the SIGSEGV exception???


  • Moderators

    Hi,

    Please check the following code:
    Check the SLOT CheckAllCheckBoxes(bool)

    installer.cpp

    @#include "installer.h"

    Installer::Installer(QWidget *parent)
    : QWizard(parent)
    {
    setPage(Page_Intro, new IntroPage);
    setPage(Page_Register, new RegisterPage);
    setStartId(Page_Intro);
    setWindowTitle(tr("Test Wizard"));

    }

    Installer::~Installer()
    {

    }

    IntroPage::IntroPage(QWidget *parent)
    : QWizardPage(parent)
    {
    setTitle(tr("Introduction"));
    }

    void IntroPage::initializePage()
    {
    topLabel = new QLabel(tr("Test Wizard. \n Please click next to install"));
    topLabel->setWordWrap(true);

    m_one = new QCheckBox();m_one->setText("one");
    connect(m_one,SIGNAL(clicked(bool)),this,SLOT(CheckAllCheckBoxes(bool)));
    m_two = new QCheckBox();m_two->setText("two");
    connect(m_two,SIGNAL(clicked(bool)),this,SLOT(CheckAllCheckBoxes(bool)));
    m_three = new QCheckBox();m_three->setText("three");
    connect(m_three,SIGNAL(clicked(bool)),this,SLOT(CheckAllCheckBoxes(bool)));
    m_four = new QCheckBox();m_four->setText("four");
    connect(m_four,SIGNAL(clicked(bool)),this,SLOT(CheckAllCheckBoxes(bool)));
    
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(topLabel);
    
    layout->addWidget(m_one);
    layout->addWidget(m_two);
    layout->addWidget(m_three);
    layout->addWidget(m_four);
    setLayout(layout);
    

    }

    bool IntroPage::validatePage()
    {
    return Installer::Page_Register;
    }

    void IntroPage::CheckAllCheckBoxes(bool state)
    {
    int checkcount = 0;

    QList<QCheckBox *> allcheckboxes = findChildren<QCheckBox *>();
    for(int i=0;i<allcheckboxes.count();i++)
    {
        if(allcheckboxes.at(i)->isChecked())
            checkcount++;
    }
    if(checkcount>2)
        wizard()->button(QWizard::NextButton)->setEnabled(true);
    else
        wizard()->button(QWizard::NextButton)->setEnabled(false);
    

    }

    //--------------------------

    RegisterPage::RegisterPage(QWidget *parent)
    : QWizardPage(parent)
    {
    setTitle(tr("Test Wizard Page 2"));
    setSubTitle(tr("Please wait..."));

    }

    void RegisterPage::initializePage()
    {
    line = new QLineEdit;
    line->setHidden(true);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(bar,1,0);
    layout->addWidget(line,2,0);
    setLayout(layout);
    

    }

    bool RegisterPage::validatePage()
    {
    }

    int RegisterPage::EnableNextFinish()
    {
    line->setText("157");
    setSubTitle("Completed");
    }

    bool RegisterPage::isComplete()
    {
    return true;
    }
    @

    installer.h

    @#ifndef INSTALLER_H
    #define INSTALLER_H

    #include <QtGui>

    class Installer : public QWizard
    {
    Q_OBJECT

    public:
    Installer(QWidget *parent = 0);
    enum { Page_Intro,Page_Register};
    ~Installer();
    };

    class IntroPage : public QWizardPage
    {
    Q_OBJECT

    public:
    IntroPage(QWidget *parent = 0);
    bool validatePage();

    void initializePage();
    

    private:
    QLabel *topLabel;
    QCheckBox *m_one,*m_two,*m_three,*m_four;
    QRadioButton *registerRadioButton;
    QRadioButton *evaluateRadioButton;

    protected slots:
    void CheckAllCheckBoxes(bool state);
    };

    class RegisterPage : public QWizardPage
    {
    Q_OBJECT

    public:
    RegisterPage(QWidget *parent = 0);
    void initializePage();
    QLineEdit *line;
    bool validatePage();

    private:
    public slots:
    int EnableNextFinish();
    bool isComplete();
    };
    #endif // INSTALLER_H
    @



  • Thanks p3c0
    It worked save for the fact that the Next button is enabled before you actually click the checkboxes and it allows going forward to the next page.
    I don't know where to call the disabling function since i tried it in the constructor and it didn't work??


  • Moderators

    Right. Doesn't even work in initializePage(). Just wondering why it didn't work


  • Moderators

    It works in showEvent().

    Try adding this function to the above code

    @void IntroPage::showEvent(QShowEvent *)
    {
    wizard()->button(QWizard::NextButton)->setEnabled(false);
    }@



  • Thanks man it worked


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.