Почему QWizard::nextId() вызывается дважды?

У меня есть подкласс QWizard, созданный мастером форм Qt Creator. Как описано в документации, я повторно реализовал nextId() для проверки входных данных и создания нелинейного мастера. Проблема в том, что nextId() вызывается дважды: один раз при входе на страницу и один раз при выходе. Мне нужна простая проверка полей в последнюю минуту, а затем направлять пользователя на следующую страницу или показывать сообщение об ошибке и удерживать пользователя на текущей странице.

Примечание. Я создал мастер с помощью генератора форм Qt Creator. Страницы включены в файл ui. Поэтому повторная реализация QWizardPage::nextId() не вариант.

Обновление: Вот код:

int WizardBackupDatabase::nextId() const
{
    Page nextPage;
    Page currentPageType = static_cast<Page>(currentId());
    qDebug() << currentId(); // This prints twice
    switch (currentPageType) {
    case Page::Intro:
        nextPage = Page::DataSource;
        break;
    case Page::DataSource:
        if(checkSource()) {
            nextPage = Page::Settings;
        }
        else {
            nextPage = Page::DataSource;
        }
        break;
    case Page::Settings:
        if(checkSettings()) {
            nextPage = Page::Verify;
        }
        else {
            nextPage = Page::Settings;
        }
        break;
    case Page::Verify:
        nextPage = Page::Operation;
        break;
    case Page::Operation:
        return -1;
    default:
        return -1;
    }
    return static_cast<int>(nextPage);
}

person sorush-r    schedule 03.02.2014    source источник


Ответы (1)


К моменту вызова nextId вы уже намерены переключить страницу. В этот момент просто нет смысла проводить какую-либо проверку.

На самом деле это семантическая ошибка, если реализация nextId выполняет какую-либо проверку или отображает какой-либо пользовательский интерфейс. Его можно вызывать столько раз, сколько пожелает реализация, и ваш код должен с этим справляться. Просто подумайте, чему этот метод эквивалентен. Это метод запроса, мало чем отличающийся от метода size в контейнере.

Для проверки входных данных в идеале следует заново реализовать isComplete, или объявить обязательные поля, или повторно реализовать validateCurrentPage.

validateCurrentPage вызывается QWizard::next. Если он возвращает true, то вызывается nextId для запроса страницы, на которую нужно переключиться, и страницы переключаются. Частный код switchToPage снова вызывает nextId, чтобы убедиться, что следующая страница не является недействительной. Это источник двойного вызова, который вы испытываете.

Ваши звонки checkSettings вообще не относятся к nextId. Они принадлежат validateCurrentPage.

Исходный код Qt удобно доступен через браузер исходного кода woboq. Иногда исходный код лучше любой документации. Если вы считаете, что документация неполная, я уверен, что хорошо сделанный вклад, исправляющий недостаток, будет с радостью принят :)

person Kuba hasn't forgotten Monica    schedule 03.02.2014
comment
Не могу найти ничего, что намекает или поддерживает ваш ответ в документации. Можете ли вы указать мне на это? - person Shoe; 03.02.2014
comment
Документация @Jeffrey Qt написана определенным образом. Если функция указана для запроса того, что делать дальше, это именно то, что она должна делать, ни больше, ни меньше. Документация validateCurrentPage точно описывает, что хочет сделать спрашивающий. - person Kuba hasn't forgotten Monica; 03.02.2014