Защо QWizard::nextId() се извиква два пъти?

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

Забележка: Направих съветника с помощта на генератора на формуляри на Qt Creator. Страниците са включени в потребителския файл. Така че повторното внедряване на 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
@Jeffffrey Qt документацията е написана по определен начин. Ако дадена функция е зададена да пита какво да прави по-нататък, тя трябва да направи точно това, нито повече, нито по-малко. Документацията validateCurrentPage точно покрива какво иска да направи питащият. - person Kuba hasn't forgotten Monica; 03.02.2014