컨테이너 확장 기능 예시
Qt Widgets Designer 용 사용자 정의 다중 페이지 플러그인 만들기.
컨테이너 확장 예제는 ` QDesignerContainerExtension ` 클래스를 사용하여 ` Qt Widgets Designer `용 사용자 정의 다중 페이지 플러그인을 만드는 방법을 보여줍니다.
Qt Widgets Designer UI 편집기의 스크린샷" src="images/containerextension-example.webp" title="객체에 현재 페이지 앞에 페이지를 삽입하는 옵션이 표시된 Qt Widgets Designer UI 편집기의 스크린샷"/>
Qt Widgets Designer 에서 사용할 수 있는 사용자 정의 위젯을 제공하려면 독립적인 구현체를 제공해야 합니다. 이 예제에서는 컨테이너 확장 기능을 보여주기 위해 설계된 사용자 정의 다중 페이지 위젯을 사용합니다.
확장(extension)은 Qt Widgets Designer 의 동작을 수정하는 객체입니다. QDesignerContainerExtension 을 사용하면 Qt Widgets Designer 에서 사용자 정의 다중 페이지 위젯을 관리하고 조작할 수 있습니다(예: 위젯에 페이지를 추가하거나 삭제하는 등).
Qt Widgets Designer 에는 네 가지 유형의 확장이 있습니다:
- QDesignerMemberSheetExtension Qt Widgets Designer 의 신호 및 슬롯 편집 모드를 사용하여 연결을 구성할 때 표시되는 위젯의 멤버 함수를 조작할 수 있게 해주는 확장 기능을 제공합니다.
- QDesignerPropertySheetExtension Qt Widgets Designer 의 속성 편집기에 표시되며, 위젯의 속성을 조작할 수 있게 해주는 확장 기능을 제공합니다.
- QDesignerTaskMenuExtension Qt Widgets Designer 의 작업 메뉴에 사용자 정의 메뉴 항목을 추가할 수 있게 해주는 확장 기능을 제공합니다.
- QDesignerContainerExtension Qt Widgets Designer 의 다중 페이지 컨테이너 플러그인에 페이지를 추가(및 삭제)할 수 있게 해주는 확장 기능을 제공합니다.
이 예제와 동일한 패턴을 따르기만 하면, 해당 확장 기능의 기본 클래스만 교체하여 모든 확장 기능을 사용할 수 있습니다. 자세한 내용은 다음을 참조하십시오. Qt Widgets Designer C++ Classes를 참조하십시오.
'컨테이너 확장' 예제는 다음 네 가지 클래스로 구성됩니다:
MultiPageWidget는 사용자가 페이지를 조작하고 내용을 채우며, 콤보박스를 사용하여 페이지 간을 이동할 수 있게 해주는 사용자 정의 컨테이너 위젯입니다.MultiPageWidgetPlugin는MultiPageWidget클래스를 Qt Widgets Designer 에 노출시킵니다.MultiPageWidgetExtensionFactoryMultiPageWidgetContainerExtension객체를 생성합니다.MultiPageWidgetContainerExtension컨테이너 확장 기능을 제공합니다.
사용자 정의 위젯 플러그인의 프로젝트 파일은 ‘ Qt Widgets Designer ’ 내에서 정상적으로 작동하도록 하기 위해 몇 가지 추가 정보가 필요합니다. 예를 들어, 사용자 정의 위젯 플러그인은 ‘ Qt Widgets Designer ’와 함께 제공되는 컴포넌트에 의존하므로, 이를 우리가 사용하는 프로젝트 파일에 명시해야 합니다. 먼저 플러그인의 프로젝트 파일을 살펴보겠습니다.
그런 다음 MultiPageWidgetPlugin 클래스를 검토하고, MultiPageWidgetExtensionFactory 및 MultiPageWidgetContainerExtension 클래스를 살펴보겠습니다. 마지막으로 MultiPageWidget 클래스 정의를 간략히 살펴보겠습니다.
프로젝트 파일
CMake
프로젝트 파일에는 Qt Widgets Designer 라이브러리에 링크되는 플러그인을 빌드해야 한다는 내용이 명시되어야 합니다:
find_package(Qt6 REQUIRED COMPONENTS Core Designer Gui Widgets)
qt_add_plugin(containerextension)
target_link_libraries(containerextension PUBLIC
Qt::Core
Qt::Designer
Qt::Gui
Qt::Widgets
)다음 예제는 위젯의 헤더 파일과 소스 파일을 추가하는 방법을 보여줍니다:
target_sources(containerextension PRIVATE
multipagewidget.cpp multipagewidget.h
multipagewidgetcontainerextension.cpp multipagewidgetcontainerextension.h
multipagewidgetextensionfactory.cpp multipagewidgetextensionfactory.h
multipagewidgetplugin.cpp multipagewidgetplugin.h
)Qt Widgets Designer 가 사용자 정의 위젯을 사용할 수 있도록 플러그인 인터페이스의 구현체를 제공합니다. 이 예제에서는 컨테이너 확장 인터페이스와 확장 팩토리의 구현체도 함께 제공합니다.
플러그인이 Qt Widgets Designer 가 검색하는 위치에 설치되도록 하는 것이 중요합니다. 이를 위해 프로젝트의 대상 경로를 지정하고 설치할 항목 목록에 추가합니다:
set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer")
install(TARGETS containerextension
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)컨테이너 확장 기능은 라이브러리 형태로 생성됩니다. 프로젝트가 설치되면( ninja install 또는 이에 상응하는 설치 절차를 통해) 다른 Qt Widgets Designer 플러그인과 함께 설치됩니다.
플러그인에 대한 자세한 내용은 ‘Qt 플러그인 생성 방법’ 문서를 참조하십시오.
qmake
다음 예제는 플러그인을 Qt Widgets Designer 라이브러리에 링크하는 방법을 보여줍니다:
TEMPLATE = lib
CONFIG += plugin
QT += widgets designer다음 예제는 위젯의 헤더 파일과 소스 파일을 추가하는 방법을 보여줍니다:
HEADERS += multipagewidget.h \
multipagewidgetplugin.h \
multipagewidgetcontainerextension.h \
multipagewidgetextensionfactory.h
SOURCES += multipagewidget.cpp \
multipagewidgetplugin.cpp \
multipagewidgetcontainerextension.cpp \
multipagewidgetextensionfactory.cpp
OTHER_FILES += multipagewidget.json다음 예제는 Qt Widgets Designer 의 플러그인 경로에 플러그인을 설치하는 방법을 보여줍니다:
target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += targetMultiPageWidgetPlugin 클래스 정의
MultiPageWidgetPlugin 클래스는 MultiPageWidget 클래스를 Qt Widgets Designer 에 노출합니다. 이 클래스의 정의는 자세히 설명된 ‘사용자 정의 위젯 플러그인’ 예제의 플러그인 클래스와 유사합니다. 이 특정 사용자 정의 위젯에 고유한 클래스 정의 부분은 클래스 이름과 몇 가지 비공개 슬롯입니다:
#ifndef MULTIPAGEWIDGETPLUGIN_H
#define MULTIPAGEWIDGETPLUGIN_H
#include <QtUiPlugin/QDesignerCustomWidgetInterface>
class QIcon;
class QWidget;
class MultiPageWidgetPlugin: public QObject, public QDesignerCustomWidgetInterface
{
Q_OBJECT
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidget")
Q_INTERFACES(QDesignerCustomWidgetInterface)
public:
explicit MultiPageWidgetPlugin(QObject *parent = nullptr);
QString name() const override;
QString group() const override;
QString toolTip() const override;
QString whatsThis() const override;
QString includeFile() const override;
QIcon icon() const override;
bool isContainer() const override;
QWidget *createWidget(QWidget *parent) override;
bool isInitialized() const override;
void initialize(QDesignerFormEditorInterface *formEditor) override;
QString domXml() const override;
private slots:
void currentIndexChanged(int index);
void pageTitleChanged(const QString &title);
private:
bool initialized = false;
};
#endif이 플러그인 클래스는 Qt Widgets Designer 에 클래스 이름 및 포함 파일과 같은 플러그인에 대한 기본 정보를 제공합니다. 또한 MultiPageWidget 위젯의 인스턴스를 생성하는 방법도 알고 있습니다. MultiPageWidgetPlugin 는 또한 플러그인이 Qt Widgets Designer 에 로드된 후 호출되는 initialize() 함수를 정의합니다. 이 함수의 QDesignerFormEditorInterface 매개변수는 플러그인에 Qt Widgets Designer 의 모든 API에 대한 접근 경로를 제공합니다.
저희와 같은 멀티페이지 위젯의 경우, 사용자가 다른 페이지를 보거나 페이지 제목 중 하나를 변경할 때마다 Qt Widgets Designer 의 속성 편집기를 업데이트할 수 있도록 currentIndexChanged()와 pageTitleChanged()라는 두 개의 비공개 슬롯을 구현해야 합니다. 각 페이지에 고유한 제목을 부여하기 위해, QWidget::windowTitle 속성을 사용하여 페이지 제목을 저장하기로 했습니다(자세한 내용은 containerextension/multipagewidget.cpp의 MultiPageWidget 클래스 구현을 참조하세요). 현재는 미리 정의된 속성을 자리 표시자로 사용하지 않고는 페이지에 사용자 정의 속성(예: 페이지 제목)을 추가할 방법이 없다는 점에 유의하십시오.
MultiPageWidgetPlugin 클래스는 QObject 와 QDesignerCustomWidgetInterface 를 모두 상속받습니다. 다중 상속을 사용할 때는 Q_INTERFACES() 매크로를 사용하여 모든 인터페이스(즉, Q_OBJECT 를 상속받지 않는 클래스)가 메타 객체 시스템에 알려지도록 해야 한다는 점을 기억하는 것이 중요합니다. 이를 통해 Qt Widgets Designer 는 qobject_cast()를 사용하여 QObject 포인터만으로도 지원되는 인터페이스를 조회할 수 있습니다.
Qt가 해당 위젯을 플러그인으로 인식하도록 하려면, Q_PLUGIN_METADATA() 매크로를 추가하여 위젯에 대한 관련 정보를 내보내야 합니다:
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidget")이 매크로를 사용하면 Qt Widgets Designer 에서 사용자 정의 위젯에 접근하고 생성할 수 있습니다. 이 매크로가 없으면 Qt Widgets Designer 에서 해당 위젯을 사용할 방법이 없습니다.
MultiPageWidgetPlugin 클래스 구현
MultiPageWidgetPlugin 클래스 구현은 대부분 ‘사용자 정의 위젯 플러그인’ 예제의 플러그인 클래스와 동일합니다:
MultiPageWidgetPlugin::MultiPageWidgetPlugin(QObject *parent)
: QObject(parent)
{
}
QString MultiPageWidgetPlugin::name() const
{
return u"MultiPageWidget"_s;
}
QString MultiPageWidgetPlugin::group() const
{
return u"Display Widgets [Examples]"_s;
}
QString MultiPageWidgetPlugin::toolTip() const
{
return {};
}
QString MultiPageWidgetPlugin::whatsThis() const
{
return {};
}
QString MultiPageWidgetPlugin::includeFile() const
{
return u"multipagewidget.h"_s;
}
QIcon MultiPageWidgetPlugin::icon() const
{
return {};
}
bool MultiPageWidgetPlugin::isInitialized() const
{
return initialized;
}다른 점 중 하나는 isContainer() 함수인데, 이 예제에서는 사용자 정의 위젯이 컨테이너로 사용되도록 설계되었기 때문에 이 함수가 true를 반환합니다.
bool MultiPageWidgetPlugin::isContainer() const
{
return true;
}또 다른 차이점은 사용자 정의 위젯을 생성하는 함수입니다:
QWidget *MultiPageWidgetPlugin::createWidget(QWidget *parent)
{
auto *widget = new MultiPageWidget(parent);
connect(widget, &MultiPageWidget::currentIndexChanged,
this, &MultiPageWidgetPlugin::currentIndexChanged);
connect(widget, &MultiPageWidget::pageTitleChanged,
this, &MultiPageWidgetPlugin::pageTitleChanged);
return widget;
}위젯을 생성하고 반환하는 것 외에도, 사용자가 다른 페이지를 볼 때마다 ` Qt Widgets Designer`의 속성 편집기가 업데이트되도록 사용자 정의 컨테이너 위젯의 `currentIndexChanged()` 신호를 플러그인의 `currentIndexChanged()` 슬롯에 연결합니다. 또한 위젯의 `pageTitleChanged()` 신호를 플러그인의 `pageTitleChanged()` 슬롯에 연결합니다.
currentIndexChanged() 슬롯은 사용자 정의 위젯의 currentIndexChanged() 신호가 발산될 때마다, 즉 사용자가 다른 페이지를 볼 때마다 호출됩니다:
void MultiPageWidgetPlugin::currentIndexChanged(int index)
{
Q_UNUSED(index);
auto *widget = qobject_cast<MultiPageWidget*>(sender());먼저, ` QObject::sender()` 및 ` qobject_cast()` 함수를 사용하여 신호를 발산하는 객체를 가져옵니다. 신호에 의해 활성화된 슬롯 내에서 호출된 경우, ` QObject::sender()`는 신호를 보낸 객체에 대한 포인터를 반환하고, 그렇지 않은 경우 0을 반환합니다.
if (widget) {
auto *form = QDesignerFormWindowInterface::findFormWindow(widget);
if (form)
form->emitSelectionChanged();
}
}위젯을 확보하면 속성 편집기를 업데이트할 수 있습니다. ` Qt Widgets Designer `는 ` QDesignerPropertySheetExtension ` 클래스를 사용하여 속성 편집기에 데이터를 공급하며, 작업 공간에서 위젯이 선택될 때마다 ` Qt Widgets Designer `는 해당 위젯의 속성 시트 확장 기능을 조회하여 속성 편집기를 업데이트합니다.
따라서 우리가 달성하고자 하는 것은 Qt Widgets Designer 에 위젯의 내부 선택 상태가 변경되었음을 알리는 것입니다. 먼저 정적 함수 QDesignerFormWindowInterface::findFormWindow()를 사용하여 위젯을 포함하는 QDesignerFormWindowInterface 객체를 가져옵니다. QDesignerFormWindowInterface 클래스를 사용하면 Qt Widgets Designer 의 작업 공간에 나타나는 폼 창을 조회하고 조작할 수 있습니다. 그런 다음, emitSelectionChanged() 신호를 발생시켜 속성 편집기의 업데이트를 강제하면 됩니다.
페이지 제목을 변경할 때, 실제로는 페이지의 속성 확장 기능이 업데이트되어야 하므로 속성 편집기를 일반적으로 새로 고치는 것만으로는 충분하지 않습니다. 따라서 제목을 변경하려는 페이지의 QDesignerPropertySheetExtension 객체에 접근해야 합니다. QDesignerPropertySheetExtension 클래스를 사용하면 위젯의 속성을 조작할 수도 있지만, 확장 기능을 얻으려면 먼저 Qt Widgets Designer 의 확장 관리자에 대한 액세스 권한을 확보해야 합니다:
void MultiPageWidgetPlugin::pageTitleChanged(const QString &title)
{
Q_UNUSED(title);
auto *widget = qobject_cast<MultiPageWidget*>(sender());
if (widget) {
auto *page = widget->widget(widget->currentIndex());
auto *form = QDesignerFormWindowInterface::findFormWindow(widget);다시 한번, ` QObject::sender()` 및 ` qobject_cast()` 함수를 사용하여 신호를 발산하는 위젯을 먼저 가져옵니다. 그런 다음 신호를 발산한 위젯에서 현재 페이지를 가져오고, 정적 함수 ` QDesignerFormWindowInterface::findFormWindow()`를 사용하여 해당 위젯이 포함된 폼을 가져옵니다.
auto *editor = form->core();
auto *manager = editor->extensionManager();이제 폼 창을 확보했으므로, ` QDesignerFormWindowInterface ` 클래스는 현재 ` QDesignerFormEditorInterface ` 객체를 반환하는 ` core()` 함수를 제공합니다. ` QDesignerFormEditorInterface ` 클래스를 사용하면 ` Qt Designer`의 다양한 구성 요소에 접근할 수 있습니다. 특히, ` QDesignerFormEditorInterface::extensionManager()` 함수는 현재 확장 관리자에 대한 참조를 반환합니다.
auto *sheet = qt_extension<QDesignerPropertySheetExtension*>(manager, page);
const int propertyIndex = sheet->indexOf(QLatin1String("windowTitle"));
sheet->setChanged(propertyIndex, true);
}
}
}확장 관리자를 확보하면 확장 시트를 업데이트할 수 있습니다. 먼저 qt_extension() 함수를 사용하여 제목을 변경하려는 페이지의 extension 속성을 가져옵니다. 그런 다음 QDesignerPropertySheetExtension::indexOf() 함수를 사용하여 페이지 제목의 인덱스를 가져옵니다. 앞서 언급한 바와 같이, 페이지 제목을 저장하기 위해 QWidget::windowTitle 속성을 사용하기로 했습니다(자세한 내용은 containerextension/multipagewidget.cpp의 MultiPageWidget 클래스 구현을 참조하십시오). 마지막으로, QDesignerPropertySheetExtension::setChanged() 함수를 호출하여 페이지의 속성 시트 업데이트를 암시적으로 강제합니다.
void MultiPageWidgetPlugin::initialize(QDesignerFormEditorInterface *formEditor)
{
if (initialized)
return;또한 initialize() 함수도 주목하십시오. initialize() 함수는 QDesignerFormEditorInterface 객체를 인수로 받습니다.
auto *manager = formEditor->extensionManager();사용자 정의 위젯 플러그인과 관련된 확장 기능을 생성할 때는 QDesignerFormEditorInterface 매개변수에서 가져온 Qt Widgets Designer 의 현재 확장 관리자에 접근해야 합니다.
QExtensionManager 클래스는 위젯의 속성을 조작할 수 있게 해줄 뿐만 아니라, Qt Widgets Designer 에 대한 확장 관리 기능을 제공합니다. Qt Widgets Designer 의 현재 확장 관리자를 사용하면 주어진 객체에 대한 확장을 가져올 수 있습니다. 또한 주어진 객체에 대한 확장을 등록하거나 등록을 해제할 수도 있습니다. 확장(extension)은 Qt Widgets Designer 의 동작을 수정하는 객체라는 점을 기억하십시오.
확장 기능을 등록할 때, 실제로는 관련 확장 팩토리가 등록됩니다. Qt Widgets Designer 에서는 확장 팩토리를 사용하여 필요에 따라 명명된 확장 기능을 조회하고 생성합니다. 따라서 이 예제에서, Qt Widgets Designer 가 관련 위젯이 컨테이너인지 여부를 파악해야 할 때까지는 컨테이너 확장 기능 자체가 생성되지 않습니다.
auto *factory = new MultiPageWidgetExtensionFactory(manager);
Q_ASSERT(manager != nullptr);
manager->registerExtensions(factory, Q_TYPEID(QDesignerContainerExtension));
initialized = true;
}우리는 QDesignerFormEditorInterface 매개변수에서 가져온 Qt Widgets Designer 의 현재 extension manager 를 사용하여 등록할 MultiPageWidgetExtensionFactory 객체를 생성합니다. 첫 번째 인수는 새로 생성된 팩토리이며, 두 번째 인수는 문자열 형태의 확장 식별자입니다. Q_TYPEID() 매크로는 단순히 이 문자열을 QLatin1String 로 변환합니다.
MultiPageWidgetExtensionFactory 클래스는 QExtensionFactory 의 하위 클래스입니다. Qt Widgets Designer 가 위젯이 컨테이너인지 여부를 파악해야 할 때, Qt Widgets Designer 의 확장 관리자는 등록된 모든 팩토리를 순차적으로 확인하여 해당 위젯에 대한 컨테이너 확장을 생성할 수 있는 첫 번째 팩토리를 호출합니다. 이 팩토리는 차례로 MultiPageWidgetExtension 객체를 생성합니다.
QString MultiPageWidgetPlugin::domXml() const
{
return uR"(
<ui language="c++">
<widget class="MultiPageWidget" name="multipagewidget">
<widget class="QWidget" name="page"/>
</widget>
<customwidgets>
<customwidget>
<class>MultiPageWidget</class>
<extends>QWidget</extends>
<addpagemethod>addPage</addpagemethod>
</customwidget>
</customwidgets>
</ui>)"_s;
}마지막으로, ` domXml() ` 함수를 살펴보겠습니다. 이 함수는 ` Qt Widgets Designer`에서 사용하는 표준 XML 형식으로 위젯의 기본 설정을 포함합니다. 이 경우 컨테이너의 첫 번째 페이지를 지정합니다. 다중 페이지 위젯의 초기 페이지는 반드시 이 함수 내에서 지정해야 합니다.
MultiPageWidgetExtensionFactory 클래스 정의
MultiPageWidgetExtensionFactory 클래스는 Qt Widgets Designer 에 대한 표준 확장 팩토리를 제공하는 QExtensionFactory 를 상속받습니다.
class MultiPageWidgetExtensionFactory: public QExtensionFactory
{
Q_OBJECT
public:
explicit MultiPageWidgetExtensionFactory(QExtensionManager *parent = nullptr);
protected:
QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const override;
};이 하위 클래스의 목적은 ` QExtensionFactory::createExtension()` 함수를 재구현하여 ` MultiPageWidget ` 컨테이너 확장을 생성할 수 있도록 하는 것입니다.
MultiPageWidgetExtensionFactory 클래스 구현
이 클래스의 생성자는 단순히 QExtensionFactory 기본 클래스의 생성자를 호출합니다:
MultiPageWidgetExtensionFactory::MultiPageWidgetExtensionFactory(QExtensionManager *parent)
: QExtensionFactory(parent)
{}앞서 설명한 바와 같이, Qt Widgets Designer 가 연관된 위젯이 컨테이너인지 여부를 파악해야 할 때 이 팩토리가 호출됩니다.
QObject *MultiPageWidgetExtensionFactory::createExtension(QObject *object,
const QString &iid,
QObject *parent) const
{
auto *widget = qobject_cast<MultiPageWidget*>(object);
if (widget && (iid == Q_TYPEID(QDesignerContainerExtension)))
return new MultiPageWidgetContainerExtension(widget, parent);
return nullptr;
}Qt Widgets Designer요청된 확장 기능이 컨테이너, 멤버 시트, 속성 시트 또는 작업 메뉴와 연관되어 있든 상관없이 이 팩토리의 동작은 동일합니다. 즉, 확장 관리자는 등록된 모든 확장 팩토리를 순차적으로 확인하며, 각 팩토리에 대해 createExtension() 를 호출하고, 요청된 확장 기능을 생성하여 응답하는 팩토리가 나타날 때까지 이 과정을 반복합니다.
따라서 ` MultiPageWidgetExtensionFactory::createExtension() `에서 가장 먼저 하는 일은, 확장 기능이 요청된 ` QObject`이 실제로 ` MultiPageWidget ` 객체인지 확인하는 것입니다. 그런 다음 요청된 확장 기능이 컨테이너 확장 기능인지 확인합니다.
객체가 컨테이너 확장 기능을 요청하는 MultiPageWidget인 경우, MultiPageWidgetExtension 객체를 생성하여 반환합니다. 그렇지 않은 경우, 단순히 null 포인터를 반환하여 Qt Widgets Designer 의 확장 관리자가 등록된 팩토리를 통해 검색을 계속할 수 있도록 합니다.
MultiPageWidgetContainerExtension 클래스 정의
MultiPageWidgetContainerExtension 클래스는 QDesignerContainerExtension 을 상속받으며, 이를 통해 Qt Widgets Designer 의 다중 페이지 컨테이너 플러그인에 페이지를 추가(및 삭제)할 수 있습니다.
class MultiPageWidgetContainerExtension: public QObject,
public QDesignerContainerExtension
{
Q_OBJECT
Q_INTERFACES(QDesignerContainerExtension)
public:
explicit MultiPageWidgetContainerExtension(MultiPageWidget *widget, QObject *parent);
bool canAddWidget() const override;
void addWidget(QWidget *widget) override;
int count() const override;
int currentIndex() const override;
void insertWidget(int index, QWidget *widget) override;
bool canRemove(int index) const override;
void remove(int index) override;
void setCurrentIndex(int index) override;
QWidget *widget(int index) const override;
private:
MultiPageWidget *myWidget;
};QDesignerContainerExtension 클래스는 Qt Widgets Designer 가 사용자 정의 다중 페이지 위젯의 기능에 접근할 수 있도록 하는 용도로만 사용된다는 점을 유의해야 합니다. 사용자 정의 다중 페이지 위젯은 확장 기능의 함수에 해당하는 기능을 구현해야 합니다.
또한, 부모 위젯과 작업 메뉴가 요청된 MultiPageWidget 객체라는 두 개의 인자를 받는 생성자를 구현한다는 점에도 유의하십시오.
QDesignerContainerExtension 기본적으로 Qt Widgets Designer 의 작업 메뉴에 몇 가지 메뉴 항목을 제공하여, 사용자가 Qt Widgets Designer 의 작업 공간에서 관련 사용자 정의 다중 페이지 위젯에 페이지를 추가하거나 삭제할 수 있도록 합니다.
MultiPageWidgetContainerExtension 클래스 구현
생성자에서 매개변수로 전달된 MultiPageWidget 객체, 즉 확장 기능과 연결된 위젯에 대한 참조를 저장합니다. 이는 나중에 요청된 작업을 수행하는 사용자 정의 다중 페이지 위젯에 접근할 때 필요합니다.
MultiPageWidgetContainerExtension::MultiPageWidgetContainerExtension(MultiPageWidget *widget,
QObject *parent)
: QObject(parent)
, myWidget(widget)
{
}Qt Widgets Designer 가 사용자 정의 다중 페이지 위젯을 완전히 관리하고 조작할 수 있도록 하려면, QDesignerContainerExtension 의 모든 함수를 재구현해야 합니다:
bool MultiPageWidgetContainerExtension::canAddWidget() const
{
return true;
}
void MultiPageWidgetContainerExtension::addWidget(QWidget *widget)
{
myWidget->addPage(widget);
}
int MultiPageWidgetContainerExtension::count() const
{
return myWidget->count();
}
int MultiPageWidgetContainerExtension::currentIndex() const
{
return myWidget->currentIndex();
}canAddWidget() 및 addWidget()을 재구현하여 지정된 페이지를 컨테이너에 추가하고, count()을 재구현하여 컨테이너 내 페이지 수를 반환하며, currentIndex()을 재구현하여 현재 선택된 페이지의 인덱스를 반환해야 합니다.
void MultiPageWidgetContainerExtension::insertWidget(int index, QWidget *widget)
{
myWidget->insertPage(index, widget);
}
bool MultiPageWidgetContainerExtension::canRemove(int index) const
{
Q_UNUSED(index);
return true;
}
void MultiPageWidgetContainerExtension::remove(int index)
{
myWidget->removePage(index);
}
void MultiPageWidgetContainerExtension::setCurrentIndex(int index)
{
myWidget->setCurrentIndex(index);
}
QWidget* MultiPageWidgetContainerExtension::widget(int index) const
{
return myWidget->widget(index);
}insertWidget() 메서드를 재구현하여 주어진 페이지를 컨테이너의 지정된 인덱스에 추가하고, canRemove() 및 remove() 메서드를 재구현하여 지정된 인덱스의 페이지를 삭제하며, setCurrentIndex() 메서드를 재구현하여 현재 선택된 페이지의 인덱스를 설정하고, 마지막으로 widget() 메서드를 재구현하여 지정된 인덱스의 페이지를 반환해야 합니다.
MultiPageWidget 클래스 정의
MultiPageWidget 클래스는 사용자가 페이지를 조작하고 채울 수 있으며, 콤보박스를 사용하여 페이지 간을 이동할 수 있게 해주는 사용자 정의 컨테이너 위젯입니다.
class MultiPageWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex)
Q_PROPERTY(QString pageTitle READ pageTitle WRITE setPageTitle STORED false)
public:
explicit MultiPageWidget(QWidget *parent = nullptr);
QSize sizeHint() const override;
int count() const;
int currentIndex() const;
QWidget *widget(int index);
QString pageTitle() const;
public slots:
void addPage(QWidget *page);
void insertPage(int index, QWidget *page);
void removePage(int index);
void setPageTitle(const QString &newTitle);
void setCurrentIndex(int index);
private slots:
void pageWindowTitleChanged();
signals:
void currentIndexChanged(int index);
void pageTitleChanged(const QString &title);
private:
QStackedWidget *stackWidget;
QComboBox *comboBox;
};주목해야 할 주요 사항은, QDesignerContainerExtension 클래스는 사용자 정의 다중 페이지 위젯의 기능에 대한 Qt Designer 접근을 제공하기 위한 목적으로만 사용되므로, 사용자 정의 다중 페이지 위젯은 QDesignerContainerExtension 의 멤버 함수에 해당하는 기능을 구현해야 한다는 점입니다.
또한, currentIndex 및 pageTitle 속성과 이에 연관된 set 및 get 함수를 선언합니다. 이러한 속성을 속성으로 선언함으로써, Qt Widgets Designer 가 MultiPageWidget 위젯이 QWidget 및 QObject 에서 상속받은 속성을 관리하는 것과 동일한 방식으로 이를 관리할 수 있게 하며, 예를 들어 속성 편집기 기능을 활용할 수 있습니다.
pageTitle 속성 선언에 있는 STORED 속성에 주목하십시오. STORED 속성은 지속성을 나타내며, 즉 객체의 상태를 저장할 때 해당 속성의 값을 기억해야 하는지 여부를 선언합니다. 앞서 언급했듯이, 각 페이지에 고유한 제목을 부여할 수 있도록 QWidget::windowTitle 속성을 사용하여 페이지 제목을 저장하기로 했습니다. 따라서 pageTitle 속성은 편집 목적으로 제공되는 "가짜" 속성이므로 저장할 필요가 없습니다.
또한 사용자가 다른 페이지를 보거나 페이지 제목 중 하나를 변경할 때마다 Qt Widgets Designer 의 속성 편집기가 업데이트되도록 currentIndexChanged() 및 pageTitleChanged() 신호를 구현하고 발신해야 합니다.
자세한 내용은 containerextension/multipagewidget.cpp에 있는 MultiPageWidget 클래스 구현을 참조하십시오.
© 2026 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.