라이선스 마법사 예제
라이센스 마법사 예제는 Qt에서 복잡한 마법사를 구현하는 방법을 보여줍니다.
대부분의 마법사는 1페이지에 이어 2페이지, 그리고 마지막 페이지까지 이어지는 선형 구조를 가지고 있습니다. Trivial 마법사 예제는 이러한 마법사를 만드는 방법을 보여줍니다.
일부 마법사는 사용자가 제공한 정보에 따라 다양한 이동 경로를 허용한다는 점에서 더 복잡합니다. 라이선스 마법사 예제가 이를 보여줍니다. 이 마법사는 여러 마법사 페이지를 제공하며, 어떤 옵션을 선택하느냐에 따라 사용자가 다른 페이지로 이동할 수 있습니다.
이 예제는 다음 클래스로 구성됩니다:
LicenseWizard
QWizard 을 상속하여 사용자가 라이선스 계약을 선택하는 과정을 안내하는 비선형 5페이지 마법사를 구현합니다.IntroPage
,EvaluatePage
,RegisterPage
,DetailsPage
,ConclusionPage
은 마법사 페이지를 구현하는 QWizardPage 서브클래스입니다.
LicenseWizard 클래스
LicenseWizard
클래스는 QWizard 에서 파생되며 가상의 소프트웨어 제품 사본을 등록하는 과정을 사용자에게 안내하는 5페이지 분량의 마법사를 제공합니다. 다음은 클래스 정의입니다:
class LicenseWizard : public QWizard { Q_OBJECT public: enum { Page_Intro, Page_Evaluate, Page_Register, Page_Details, Page_Conclusion }; LicenseWizard(QWidget *parent = nullptr); private slots: void showHelp(); };
클래스의 공용 API는 생성자와 열거형으로 제한됩니다. 열거형은 다양한 페이지와 관련된 ID를 정의합니다:
클래스 이름 | 열거형 값 | 페이지 ID |
---|---|---|
IntroPage | Page_Intro | 0 |
EvaluatePage | Page_Evaluate | 1 |
RegisterPage | Page_Register | 2 |
DetailsPage | Page_Details | 3 |
ConclusionPage | Page_Conclusion | 4 |
이 예제에서 ID는 임의입니다. 유일한 제약 조건은 고유하고 -1과 달라야 한다는 것입니다. ID를 사용하면 페이지를 참조할 수 있습니다.
LicenseWizard::LicenseWizard(QWidget *parent) : QWizard(parent) { setPage(Page_Intro, new IntroPage); setPage(Page_Evaluate, new EvaluatePage); setPage(Page_Register, new RegisterPage); setPage(Page_Details, new DetailsPage); setPage(Page_Conclusion, new ConclusionPage); setStartId(Page_Intro);
생성자에서 5개의 페이지를 생성하고 QWizard::setPage()를 사용하여 마법사에 삽입한 다음 Page_Intro
을 첫 번째 페이지로 설정합니다.
#ifndef Q_OS_MAC setWizardStyle(ModernStyle); #endif
macOS를 제외한 모든 플랫폼에서 스타일을 ModernStyle 로 설정합니다,
setOption(HaveHelpButton, true); setPixmap(QWizard::LogoPixmap, QPixmap(":/images/logo.png")); connect(this, &QWizard::helpRequested, this, &LicenseWizard::showHelp); setWindowTitle(tr("License Wizard")); }
showHelp()
슬롯에 연결된 Help 버튼이 표시되도록 QWizard 을 구성합니다. 또한 헤더가 있는 모든 페이지(예: EvaluatePage
, RegisterPage
, DetailsPage
)에 대해 LogoPixmap 을 설정합니다.
void LicenseWizard::showHelp() { static QString lastHelpMessage; QString message; switch (currentId()) { case Page_Intro: message = tr("The decision you make here will affect which page you " "get to see next."); break; ... default: message = tr("This help is likely not to be of any help."); } if (lastHelpMessage == message) message = tr("Sorry, I already gave what help I could. " "Maybe you should try asking a human?"); QMessageBox::information(this, tr("License Wizard Help"), message); lastHelpMessage = message; }
showHelp()
에서는 현재 페이지에 적합한 도움말 텍스트를 표시합니다. 사용자가 같은 페이지에 대해 Help 을 두 번 클릭하면 "죄송합니다. 이미 가능한 도움말을 제공했습니다. 사람에게 문의해 보시겠습니까?"라는 메시지가 표시됩니다.
IntroPage 클래스
페이지는 licensewizard.h
에 정의되어 있고 licensewizard.cpp
에서 LicenseWizard
와 함께 구현되어 있습니다.
다음은 IntroPage
의 정의와 구현입니다:
class IntroPage : public QWizardPage { Q_OBJECT public: IntroPage(QWidget *parent = nullptr); int nextId() const override; private: QLabel *topLabel; QRadioButton *registerRadioButton; QRadioButton *evaluateRadioButton; }; IntroPage::IntroPage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Introduction")); setPixmap(QWizard::WatermarkPixmap, QPixmap(":/images/watermark.png")); topLabel = new QLabel(tr("This wizard will help you register your copy of " "<i>Super Product One</i>™ or start " "evaluating the product.")); topLabel->setWordWrap(true); registerRadioButton = new QRadioButton(tr("&Register your copy")); evaluateRadioButton = new QRadioButton(tr("&Evaluate the product for 30 " "days")); registerRadioButton->setChecked(true); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(topLabel); layout->addWidget(registerRadioButton); layout->addWidget(evaluateRadioButton); setLayout(layout); }
페이지는 QWizardPage 에서 상속합니다. title 과 watermark pixmap 을 설정합니다. subTitle 을 설정하지 않음으로써 이 페이지에 헤더가 표시되지 않도록 합니다. (Windows에서는 마법사가 첫 페이지와 마지막 페이지에 워터마크 픽셀맵을 표시하고 다른 페이지에 헤더를 표시하는 것이 일반적입니다.)
int IntroPage::nextId() const { if (evaluateRadioButton->isChecked()) { return LicenseWizard::Page_Evaluate; } else { return LicenseWizard::Page_Register; } }
nextId()
함수는 Evaluate the product for 30 days 옵션이 선택되어 있으면 EvaluatePage
의 ID를 반환하고, 그렇지 않으면 RegisterPage
의 ID를 반환합니다.
페이지 평가 클래스
EvaluatePage
함수는 약간 더 복잡합니다:
class EvaluatePage : public QWizardPage { Q_OBJECT public: EvaluatePage(QWidget *parent = nullptr); int nextId() const override; private: QLabel *nameLabel; QLabel *emailLabel; QLineEdit *nameLineEdit; QLineEdit *emailLineEdit; }; EvaluatePage::EvaluatePage(QWidget *parent) : QWizardPage(parent) { setTitle(tr("Evaluate <i>Super Product One</i>™")); setSubTitle(tr("Please fill both fields. Make sure to provide a valid " "email address (e.g., john.smith@example.com).")); nameLabel = new QLabel(tr("N&ame:")); nameLineEdit = new QLineEdit; ... registerField("evaluate.name*", nameLineEdit); registerField("evaluate.email*", emailLineEdit); ... }
먼저 페이지의 title 와 subTitle 을 설정합니다.
그런 다음 자식 위젯을 만들고, 그와 연결된 wizard fields 을 만든 다음 레이아웃에 넣습니다. 필드는 이름 옆에 별표(*
)가 표시되어 생성됩니다. 이렇게 하면 mandatory fields, 즉 사용자가 Next 버튼(macOS의 경우Continue )을 누르기 전에 채워야 하는 필드가 됩니다. 필드 값은 QWizardPage::field()를 사용하여 다른 페이지에서 액세스할 수 있습니다.
페이지를 재설정하면 두 텍스트 필드를 지우는 것과 같습니다.
int EvaluatePage::nextId() const { return LicenseWizard::Page_Conclusion; }
다음 페이지는 항상 ConclusionPage
입니다.
결론 페이지 클래스
RegisterPage
및 DetailsPage
은 EvaluatePage
과 매우 유사합니다. ConclusionPage
로 직접 가보겠습니다:
class ConclusionPage : public QWizardPage { Q_OBJECT public: ConclusionPage(QWidget *parent = nullptr); void initializePage() override; int nextId() const override; void setVisible(bool visible) override; private slots: void printButtonClicked(); private: QLabel *bottomLabel; QCheckBox *agreeCheckBox; };
이번에는 nextId() 외에 QWizardPage::initializePage() 및 QWidget::setVisible()를 다시 구현합니다. 또한 비공개 슬롯을 선언합니다: printButtonClicked()
.
int IntroPage::nextId() const { if (evaluateRadioButton->isChecked()) { return LicenseWizard::Page_Evaluate; } else { return LicenseWizard::Page_Register; } }
QWizardPage::nextId()의 기본 구현은 다음 ID를 가진 페이지를 반환하거나 현재 페이지의 ID가 가장 높은 경우 -1을 반환합니다. Page_Conclusion
이 5이고 더 높은 ID를 가진 페이지가 없기 때문에 이 동작은 여기서 작동하지만, 이러한 미묘한 동작에 의존하지 않기 위해 nextId()을 다시 구현하여 -1을 반환합니다.
void ConclusionPage::initializePage() { QString licenseText; if (wizard()->hasVisitedPage(LicenseWizard::Page_Evaluate)) { licenseText = tr("<u>Evaluation License Agreement:</u> " "You can use this software for 30 days and make one " "backup, but you are not allowed to distribute it."); } else if (wizard()->hasVisitedPage(LicenseWizard::Page_Details)) { const QString emailAddress = field("details.email").toString(); licenseText = tr("<u>First-Time License Agreement:</u> " "You can use this software subject to the license " "you will receive by email sent to %1.").arg(emailAddress); } else { licenseText = tr("<u>Upgrade License Agreement:</u> " "This software is licensed under the terms of your " "current license."); } bottomLabel->setText(licenseText); }
QWizard::hasVisitedPage()를 사용하여 사용자가 선택한 라이선스 계약 유형을 확인합니다. 사용자가 EvaluatePage
를 입력한 경우 라이선스 텍스트는 평가판 라이선스 계약을 의미합니다. 사용자가 DetailsPage
을 입력한 경우 라이선스 텍스트는 최초 라이선스 계약입니다. 사용자가 업그레이드 키를 제공하고 DetailsPage
을 건너뛴 경우 라이선스 텍스트는 업데이트 라이선스 계약입니다.
void ConclusionPage::setVisible(bool visible) { QWizardPage::setVisible(visible); if (visible) { wizard()->setButtonText(QWizard::CustomButton1, tr("&Print")); wizard()->setOption(QWizard::HaveCustomButton1, true); connect(wizard(), &QWizard::customButtonClicked, this, &ConclusionPage::printButtonClicked); } else { wizard()->setOption(QWizard::HaveCustomButton1, false); disconnect(wizard(), &QWizard::customButtonClicked, this, &ConclusionPage::printButtonClicked); } }
ConclusionPage
이 표시되면 마법사에 Print 버튼을 표시하고 싶습니다. 이를 수행하는 한 가지 방법은 QWidget::setVisible()를 다시 구현하는 것입니다:
- 페이지가 표시되면 CustomButton1 버튼의 텍스트를 다음과 같이 설정합니다. Print로 설정하고 HaveCustomButton1 옵션을 활성화한 다음 QWizard 의 customButtonClicked() 신호를
printButtonClicked()
슬롯에 연결합니다. - 페이지가 숨겨져 있으면 HaveCustomButton1 옵션을 비활성화하고
printButtonClicked()
슬롯의 연결을 끊습니다.
QWizard 및 사소한 마법사 예제도참조하세요 .
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.