이 페이지에서

작업 메뉴 확장 기능

Qt Widgets Designer 용 사용자 정의 위젯 플러그인을 만들고, 해당 플러그인과 연동되는 사용자 정의 작업 메뉴 항목을 제공하는 방법.

'작업 메뉴 확장' 예제는 Qt Widgets Designer, 그리고 QDesignerTaskMenuExtension 클래스를 사용하여 플러그인과 연관된 사용자 정의 작업 메뉴 항목을 제공하는 방법을 보여줍니다.

<span translate=Qt Widgets Designer의 컨텍스트 메뉴에 있는 사용자 정의 “상태 편집...” 작업의 스크린샷." src="images/taskmenuextension-example.webp" title="Qt Widgets Designer의 컨텍스트 메뉴에 있는 사용자 정의 “상태 편집...” 작업의 스크린샷."/>

Qt Widgets Designer 와 함께 사용할 수 있는 사용자 정의 위젯을 제공하려면, 독립적인 구현을 제공해야 합니다. 이 예제에서는 작업 메뉴 확장 기능을 표시하도록 설계된 사용자 정의 위젯인 TicTacToe 위젯을 사용합니다.

확장(extension)이란 Qt Widgets Designer 의 동작을 수정하는 객체를 말합니다. QDesignerTaskMenuExtension 는 이 확장을 가진 위젯이 선택되었을 때 사용자 정의 작업 메뉴 항목을 제공할 수 있습니다.

Qt Widgets Designer 에는 네 가지 유형의 확장이 있습니다:

  • QDesignerContainerExtension Qt Widgets Designer 의 다중 페이지 컨테이너 플러그인에 페이지를 추가(및 삭제)할 수 있게 해주는 확장 기능을 제공합니다.
  • QDesignerMemberSheetExtension Qt Widgets Designer 의 신호 및 슬롯 편집 모드를 사용하여 연결을 구성할 때 표시되는 위젯의 멤버 함수를 조작할 수 있게 해주는 확장 기능을 제공합니다.
  • QDesignerPropertySheetExtension Qt Widgets Designer 의 속성 편집기에 표시되는 위젯의 속성을 조작할 수 있게 해주는 확장 기능을 제공합니다.
  • QDesignerTaskMenuExtension Qt Widgets Designer 의 작업 메뉴에 사용자 정의 메뉴 항목을 추가할 수 있게 해주는 확장 기능을 제공합니다.

이 예제와 동일한 패턴을 따르면서 해당 확장 기능의 기본 클래스만 교체하면 모든 확장 기능을 사용할 수 있습니다. 자세한 내용은 Qt Widgets Designer C++ Classes를 참조하십시오.

'작업 메뉴 확장' 예제는 다음 다섯 개의 클래스로 구성됩니다:

  • TicTacToe 는 사용자가 틱택토 게임을 즐길 수 있게 해주는 사용자 정의 위젯입니다.
  • TicTacToePlugin 는 TicTacToe 클래스를 Qt Widgets Designer 에 노출합니다.
  • TicTacToeTaskMenuFactory TicTacToeTaskMenu 객체를 생성합니다.
  • TicTacToeTaskMenu 태스크 메뉴 확장 기능, 즉 플러그인과 연관된 태스크 메뉴 항목을 제공합니다.
  • TicTacToeDialog 사용자가 Qt Widgets Designer 에 로드된 Tic-Tac-Toe 플러그인의 상태를 수정할 수 있게 합니다.

사용자 정의 위젯 플러그인의 프로젝트 파일에는 Qt Widgets Designer 내에서 제대로 작동하도록 하기 위해 몇 가지 추가 정보가 필요합니다. 예를 들어, 사용자 정의 위젯 플러그인은 Qt Widgets Designer 에서 제공하는 컴포넌트에 의존하며, 이는 우리가 사용하는 프로젝트 파일에 명시되어야 합니다. 먼저 플러그인의 프로젝트 파일을 살펴보겠습니다.

그런 다음 TicTacToePlugin 클래스를 살펴보고, TicTacToeTaskMenuFactory 및 TicTacToeTaskMenu 클래스도 살펴보겠습니다. 마지막으로 TicTacToeDialog 클래스를 검토한 후, TicTacToe 위젯의 클래스 정의를 간략히 살펴보겠습니다.

프로젝트 파일

CMake

프로젝트 파일에는 Qt Widgets Designer 라이브러리에 링크되는 플러그인을 빌드해야 한다는 내용이 명시되어야 합니다:

find_package(Qt6 REQUIRED COMPONENTS Core Designer Gui Widgets)

qt_add_plugin(taskmenuextension)

target_link_libraries(taskmenuextension PUBLIC
    Qt::Core
    Qt::Designer
    Qt::Gui
    Qt::Widgets
)

다음 예제는 위젯의 헤더 파일과 소스 파일을 추가하는 방법을 보여줍니다:

target_sources(taskmenuextension PRIVATE
    tictactoe.cpp tictactoe.h
    tictactoedialog.cpp tictactoedialog.h
    tictactoeplugin.cpp tictactoeplugin.h
    tictactoetaskmenu.cpp tictactoetaskmenu.h
)

Qt Widgets Designer 가 사용자 정의 위젯을 사용할 수 있도록 플러그인 인터페이스의 구현체를 제공합니다. 이 예제에서는 작업 메뉴 확장 및 확장 팩토리의 구현체와 대화 상자 구현체도 함께 제공합니다.

플러그인이 Qt Widgets Designer 에서 검색하는 위치에 설치되도록 하는 것이 중요합니다. 이를 위해 프로젝트의 대상 경로를 지정하고, 설치할 항목 목록에 추가합니다:

   set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer")
install(TARGETS taskmenuextension
    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 += tictactoe.h \
           tictactoedialog.h \
           tictactoeplugin.h \
           tictactoetaskmenu.h
SOURCES += tictactoe.cpp \
           tictactoedialog.cpp \
           tictactoeplugin.cpp \
           tictactoetaskmenu.cpp
OTHER_FILES += tictactoe.json

다음 예제는 Qt Widgets Designer 의 플러그인 경로에 플러그인을 설치하는 방법을 보여줍니다:

target.path = $$[QT_INSTALL_PLUGINS]/designer
INSTALLS += target

TicTacToePlugin 클래스 정의

TicTacToePlugin 클래스는 the TicTacToe 클래스를 Qt Widgets Designer 에 노출합니다. 이 정의는 자세히 설명된 '사용자 정의 위젯 플러그인' 예제의 플러그인 클래스와 동일합니다. 이 특정 사용자 정의 위젯에 고유한 클래스 정의 부분은 클래스 이름뿐입니다.

Qt가 이 위젯을 플러그인으로 인식할 수 있도록 하려면, Q_PLUGIN_METADATA() 매크로를 추가하여 위젯에 대한 관련 정보를 내보내야 합니다:

#ifndef TICTACTOEPLUGIN_H
#define TICTACTOEPLUGIN_H

#include <QtUiPlugin/QDesignerCustomWidgetInterface>

class QIcon;
class QWidget;

class TicTacToePlugin : public QObject, public QDesignerCustomWidgetInterface
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")
    Q_INTERFACES(QDesignerCustomWidgetInterface)

public:
    explicit TicTacToePlugin(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:
    bool initialized = false;
};

#endif

이 플러그인 클래스는 Qt Widgets Designer 에 클래스 이름 및 포함 파일과 같은 플러그인에 대한 기본 정보를 제공합니다. 또한 이 클래스는 TicTacToe 위젯의 인스턴스를 생성하는 방법을 알고 있습니다. TicTacToePlugin은 또한 플러그인이 Qt Widgets Designer 에 로드된 후 호출되는 initialize() 함수를 정의합니다. 이 함수의 QDesignerFormEditorInterface 매개변수는 플러그인에 Qt Widgets Designer 의 모든 API에 대한 접근 경로를 제공합니다.

TicTacToePlugin 클래스는 QObject 와 QDesignerCustomWidgetInterface 를 모두 상속받습니다. 다중 상속을 사용할 때는 Q_INTERFACES() 매크로를 사용하여 모든 인터페이스(즉, Q_OBJECT 를 상속받지 않는 클래스)가 메타 객체 시스템에 알려지도록 해야 한다는 점을 기억하는 것이 중요합니다. 이를 통해 Qt Widgets Designer 는 qobject_cast()를 사용하여 QObject 포인터만으로도 지원되는 인터페이스를 조회할 수 있습니다.

TicTacToePlugin 클래스 구현

TicTacToePlugin 클래스의 구현은 대부분 Custom Widget Plugin 예제의 플러그인 클래스와 동일합니다:

TicTacToePlugin::TicTacToePlugin(QObject *parent)
    : QObject(parent)
{
}

QString TicTacToePlugin::name() const
{
    return u"TicTacToe"_s;
}

QString TicTacToePlugin::group() const
{
    return u"Display Widgets [Examples]"_s;
}

QString TicTacToePlugin::toolTip() const
{
    return u"Tic Tac Toe Example, demonstrating class QDesignerTaskMenuExtension (C++)"_s;
}

QString TicTacToePlugin::whatsThis() const
{
    return {};
}

QString TicTacToePlugin::includeFile() const
{
    return u"tictactoe.h"_s;
}

QIcon TicTacToePlugin::icon() const
{
    return {};
}

bool TicTacToePlugin::isContainer() const
{
    return false;
}

QWidget *TicTacToePlugin::createWidget(QWidget *parent)
{
    auto *ticTacToe = new TicTacToe(parent);
    ticTacToe->setState(u"-X-XO----"_s);
    return ticTacToe;
}

bool TicTacToePlugin::isInitialized() const
{
    return initialized;
}

유일하게 크게 다른 함수는 initialize() 함수입니다:

void TicTacToePlugin::initialize(QDesignerFormEditorInterface *formEditor)
{

initialize() 함수는 QDesignerFormEditorInterface 객체를 인수로 받습니다. QDesignerFormEditorInterface 클래스는 Qt Widgets Designer 의 구성 요소에 대한 액세스를 제공합니다.

Qt Widgets Designer 에서는 사용자 정의 위젯 플러그인과 도구 플러그인, 두 가지 종류의 플러그인을 생성할 수 있습니다. QDesignerFormEditorInterface 는 도구 플러그인을 만드는 데 일반적으로 필요한 모든 Qt Widgets Designer 구성 요소(확장 관리자, 객체 검사기, 속성 편집기 및 위젯 상자)에 대한 액세스를 제공합니다. 사용자 정의 위젯 플러그인도 동일한 구성 요소에 액세스할 수 있습니다.

    if (initialized)
        return;

    auto *manager = formEditor->extensionManager();
    Q_ASSERT(manager != nullptr);

사용자 정의 위젯 플러그인과 관련된 확장 기능을 만들 때는 Qt Widgets Designer 의 현재 확장 관리자에 접근해야 하며, 이는 QDesignerFormEditorInterface 매개변수를 통해 가져옵니다.

Qt Widgets Designer QDesignerFormEditorInterface 은 의 모든 구성 요소(액션 편집기, 객체 검사기, 속성 편집기, 위젯 상자, 확장 및 양식 창 관리자)에 대한 정보를 보유하고 있습니다. Qt Designer

QExtensionManager 클래스는 Qt Widgets Designer 에 대한 확장 관리 기능을 제공합니다. Qt Widgets Designer 의 현재 확장 관리자를 사용하면 주어진 객체에 대한 확장을 가져올 수 있습니다. 또한 주어진 객체에 대한 확장을 등록하거나 등록을 해제할 수도 있습니다. 확장은 Qt Widgets Designer 의 동작을 수정하는 객체라는 점을 기억하십시오.

확장 기능을 등록할 때, 실제로는 관련 확장 팩토리가 등록됩니다. Qt Widgets Designer 에서는 확장 팩토리를 사용하여 필요에 따라 명명된 확장 기능을 조회하고 생성합니다. 따라서 이 예제에서 작업 메뉴 확장 기능 자체는 사용자가 작업 메뉴를 요청할 때까지 생성되지 않습니다.

    manager->registerExtensions(new TicTacToeTaskMenuFactory(manager),
                                Q_TYPEID(QDesignerTaskMenuExtension));

    initialized = true;
}

QString TicTacToePlugin::domXml() const
{
    return uR"(
<ui language="c++">
    <widget class="TicTacToe" name="ticTacToe"/>
    <customwidgets>
        <customwidget>
            <class>TicTacToe</class>
            <propertyspecifications>
            <tooltip name="state">Tic Tac Toe state</tooltip>
            <stringpropertyspecification name="state" notr="true" type="singleline"/>
            </propertyspecifications>
        </customwidget>
    </customwidgets>
</ui>
)"_s;
}

우리는 Qt Widgets Designer 의 QDesignerFormEditorInterface 매개변수에서 가져온 현재 extension manager 를 사용하여 등록할 TicTacToeTaskMenuFactory 객체를 생성합니다. 첫 번째 인수는 새로 생성된 팩토리이며, 두 번째 인수는 문자열 형태의 확장 식별자입니다. Q_TYPEID() 매크로는 단순히 이 문자열을 QLatin1String 로 변환합니다.

TicTacToeTaskMenuFactory 클래스는 QExtensionFactory 의 하위 클래스입니다. 사용자가 지정된 작업 메뉴 확장자를 가진 위젯 위에서 마우스 오른쪽 버튼을 클릭하여 작업 메뉴를 요청하면, Qt Widgets Designer 의 확장 관리자는 등록된 모든 팩토리를 순차적으로 확인하여, 선택된 위젯에 대한 작업 메뉴 확장자를 생성할 수 있는 첫 번째 팩토리를 호출합니다. 이 팩토리는 차례로 TicTacToeTaskMenu 객체(확장자)를 생성합니다.

기본값이 필요하지 않으므로, QDesignerCustomWidgetInterface::domXml() 함수( Qt Widgets Designer 에서 사용하는 표준 XML 형식의 위젯 기본 설정을 포함함)를 재구현하는 부분은 생략합니다.

    Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QDesignerCustomWidgetInterface")

마지막으로, Qt의 플러그인 처리 클래스와 함께 사용할 수 있도록 TicTacToePlugin 클래스를 내보내기 위해 Q_PLUGIN_METADATA() 매크로를 사용합니다. 이 매크로는 Qt Widgets Designer 가 사용자 정의 위젯에 접근하고 생성할 수 있도록 보장합니다. 이 매크로가 없으면 Qt Widgets Designer 에서 해당 위젯을 사용할 방법이 없습니다.

TicTacToeTaskMenuFactory 클래스 정의

TicTacToeTaskMenuFactory 클래스는 Qt Widgets Designer 에 대한 표준 확장 팩토리를 제공하는 QExtensionFactory 을 상속받습니다.

class TicTacToeTaskMenuFactory : public QExtensionFactory
{
    Q_OBJECT

public:
    explicit TicTacToeTaskMenuFactory(QExtensionManager *parent = nullptr);

protected:
    QObject *createExtension(QObject *object, const QString &iid, QObject *parent) const override;
};

이 하위 클래스의 목적은 ` QExtensionFactory::createExtension()` 함수를 재구현하여 ` TicTacToe ` 작업 메뉴 확장을 생성할 수 있도록 하는 것입니다.

TicTacToeTaskMenuFactory 클래스 구현

이 클래스의 생성자는 단순히 QExtensionFactory 기본 클래스의 생성자를 호출합니다.

TicTacToeTaskMenuFactory::TicTacToeTaskMenuFactory(QExtensionManager *parent)
    : QExtensionFactory(parent)
{
}

위에서 설명한 바와 같이, 사용자가 Qt Widgets Designer 에 지정된 작업 메뉴 확장자를 가진 위젯 위에서 마우스 오른쪽 버튼을 클릭하여 작업 메뉴를 요청하면 팩토리가 호출됩니다.

Qt Widgets Designer요청된 확장 기능이 컨테이너, 멤버 시트, 속성 시트 또는 작업 메뉴 중 어느 것과 연관되어 있든 간에 이 클래스의 동작은 동일합니다. 즉, 확장 관리자는 등록된 모든 확장 팩토리를 순차적으로 확인하며, 각 팩토리에 대해 ` createExtension() `를 호출하고, 요청된 확장 기능을 생성하여 응답하는 팩토리가 나타날 때까지 이 과정을 반복합니다.

QObject *TicTacToeTaskMenuFactory::createExtension(QObject *object,
                                                   const QString &iid,
                                                   QObject *parent) const
{
    if (iid != Q_TYPEID(QDesignerTaskMenuExtension))
        return nullptr;

    if (auto *tic = qobject_cast<TicTacToe*>(object))
        return new TicTacToeTaskMenu(tic, parent);

    return nullptr;
}

따라서 TicTacToeTaskMenuFactory::createExtension() 에서 가장 먼저 하는 일은 요청된 확장 기능이 태스크 메뉴 확장 기능인지 확인하는 것입니다. 만약 그렇다면, 그리고 이를 요청한 위젯이 TicTacToe 위젯인 경우, TicTacToeTaskMenu 객체를 생성하여 반환합니다. 그렇지 않은 경우, 단순히 null 포인터를 반환하여 Qt Widgets Designer 의 확장 관리자가 등록된 팩토리를 계속 검색할 수 있도록 합니다.

TicTacToeTaskMenu 클래스 정의

UI 편집기에서 위젯을 변경할 수 있는 모든 옵션을 보여주는 스크린샷

TicTacToeTaskMenu 클래스는 QDesignerTaskMenuExtension 을 상속받으며, 이를 통해 Qt Widgets Designer 의 작업 메뉴에 사용자 정의 항목(QAction 형태)을 추가할 수 있습니다.

class TicTacToeTaskMenu : public QObject, public QDesignerTaskMenuExtension
{
    Q_OBJECT
    Q_INTERFACES(QDesignerTaskMenuExtension)

public:
    explicit TicTacToeTaskMenu(TicTacToe *tic, QObject *parent);

    QAction *preferredEditAction() const override;
    QList<QAction *> taskActions() const override;

private slots:
    void editState();

private:
    QAction *editStateAction;
    TicTacToe *ticTacToe;
};

preferredEditAction() 및 taskActions() 함수를 재구현합니다. 부모 위젯과 작업 메뉴가 요청된 TicTacToe 위젯이라는 두 개의 인수를 받는 생성자를 구현한다는 점에 유의하십시오.

또한 비공개 editState() 슬롯, 사용자 정의 editStateAction 함수, 그리고 상태를 수정하고자 하는 TicTacToe 위젯을 가리키는 비공개 포인터를 선언합니다.

TicTacToeTaskMenu 클래스 구현

TicTacToeTaskMenu::TicTacToeTaskMenu(TicTacToe *tic, QObject *parent)
    : QObject(parent)
    , editStateAction(new QAction(tr("Edit State..."), this))
    , ticTacToe(tic)
{
    connect(editStateAction, &QAction::triggered, this, &TicTacToeTaskMenu::editState);
}

생성자에서는 먼저 매개변수로 전달된 ‘ TicTacToe ’ 위젯, 즉 상태를 수정하고자 하는 위젯에 대한 참조를 저장합니다. 이 참조는 나중에 사용자 정의 액션이 호출될 때 필요하게 됩니다. 또한 사용자 정의 ‘ editStateAction ’를 생성하고 이를 ‘ editState() ’ 슬롯에 연결합니다.

void TicTacToeTaskMenu::editState()
{
    TicTacToeDialog dialog(ticTacToe);
    dialog.exec();
}

editState() 슬롯은 사용자가 TicTacToe 위젯의 작업 메뉴에서 ‘Edit State...’ 옵션을 선택할 때마다 호출됩니다. 이 슬롯은 위젯의 현재 상태를 표시하는 TicTacToeDialog 를 생성하며, 사용자가 게임을 플레이하여 상태를 편집할 수 있도록 합니다.

QAction *TicTacToeTaskMenu::preferredEditAction() const
{
    return editStateAction;
}

우리는 TicTacToe 위젯을 선택하고 F2 키를 누를 때 호출되어야 할 액션으로 사용자 정의 editStateAction 를 반환하도록 preferredEditAction() 함수를 재구현합니다.

QList<QAction *> TicTacToeTaskMenu::taskActions() const
{
    return QList<QAction *>{editStateAction};
}

taskActions() 함수를 재구현하여, TicTacToe 위젯의 작업 메뉴에서 기본 메뉴 항목 위에 표시될 사용자 정의 액션 목록을 반환하도록 합니다.

TicTacToeDialog 클래스 정의

위젯의 편집 상태 모드를 보여주는 스크린샷

TicTacToeDialog 클래스는 QDialog 를 상속받습니다. 이 대화 상자를 통해 사용자는 현재 선택된 Tic-Tac-Toe 플러그인의 상태를 수정할 수 있습니다.

class TicTacToeDialog : public QDialog
{
    Q_OBJECT

public:
    explicit TicTacToeDialog(TicTacToe *plugin = nullptr, QWidget *parent = nullptr);

    QSize sizeHint() const override;

private slots:
    void resetState();
    void saveState();

private:
    TicTacToe *editor;
    TicTacToe *ticTacToe;
    QDialogButtonBox *buttonBox;
};

sizeHint() 함수를 재구현합니다. 또한 resetState() 및 saveState() 라는 두 개의 비공개 슬롯을 선언합니다. 대화 상자의 버튼과 레이아웃 외에도, 사용자가 상호 작용할 수 있는 위젯을 가리키는 하나와 사용자가 상태를 편집하고자 하는 원래의 사용자 정의 위젯 플러그인을 가리키는 다른 하나, 총 두 개의 TicTacToe 포인터를 선언합니다.

TicTacToeDialog 클래스 구현

TicTacToeDialog::TicTacToeDialog(TicTacToe *tic, QWidget *parent)
    : QDialog(parent)
    , editor(new TicTacToe)
    , ticTacToe(tic)
    , buttonBox(new QDialogButtonBox(QDialogButtonBox::Ok
                                     | QDialogButtonBox::Cancel
                                     | QDialogButtonBox::Reset))
{
    editor->setState(ticTacToe->state());

    connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked,
            this, &TicTacToeDialog::resetState);
    connect(buttonBox, &QDialogButtonBox::accepted, this, &TicTacToeDialog::saveState);
    connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);

    auto *mainLayout = new QVBoxLayout(this);
    mainLayout->addWidget(editor);
    mainLayout->addWidget(buttonBox);

    setWindowTitle(tr("Edit State"));
}

생성자에서 먼저 매개변수로 전달된 TicTacToe 위젯, 즉 사용자가 상태를 수정하고자 하는 위젯에 대한 참조를 저장합니다. 그런 다음 새로운 TicTacToe 위젯을 생성하고, 이 위젯의 상태를 매개변수로 전달된 위젯의 상태와 동일하게 설정합니다.

마지막으로, 대화 상자의 버튼과 레이아웃을 생성합니다.

QSize TicTacToeDialog::sizeHint() const
{
    return {250, 250};
}

대화 상자에 적절한 크기가 지정되도록 ` sizeHint() ` 함수를 재구현합니다.

void TicTacToeDialog::resetState()
{
    editor->clearBoard();
}

사용자가 ‘재설정(Reset)’ 버튼을 누를 때마다 ‘ resetState() ’ 슬롯이 호출됩니다. 여기서 우리가 하는 유일한 작업은 편집기 위젯, 즉 대화 상자의 생성자에서 생성한 ‘ TicTacToe ’ 위젯에 대해 ‘ clearBoard() ’ 함수를 호출하는 것입니다.

void TicTacToeDialog::saveState()
{

saveState() 슬롯은 사용자가 OK 버튼을 누를 때마다 호출되며, 편집기 위젯의 상태를 우리가 수정하고자 하는 위젯으로 전달합니다. 상태 변경이 Qt Widgets Designer 에서 반영되도록 하려면, QDesignerFormWindowInterface 클래스를 사용하여 후자의 위젯의 state 속성을 설정해야 합니다.

QDesignerFormWindowInterface 이 인터페이스는 연관된 폼 창에 대한 정보를 제공할 뿐만 아니라 해당 속성을 변경할 수 있게 해줍니다. 이 인터페이스는 직접 인스턴스화되도록 의도된 것이 아니라, ` Qt Widgets Designer`의 폼 창 관리자가 제어하는 ` Qt Widgets Designer`의 현재 폼 창에 대한 액세스를 제공하기 위한 것입니다.

특정 위젯이 포함된 폼 창을 찾고 있다면, 정적 함수 QDesignerFormWindowInterface::findFormWindow()을 사용할 수 있습니다:

    if (auto *formWindow = QDesignerFormWindowInterface::findFormWindow(ticTacToe))
        formWindow->cursor()->setProperty("state", editor->state());

위젯(상태를 수정하고자 하는)의 폼 창을 가져온 후, QDesignerFormWindowInterface::cursor() 함수를 사용하여 폼 창의 커서를 가져옵니다.

QDesignerFormWindowCursorInterface 클래스는 폼 창의 텍스트 커서에 대한 인터페이스를 제공합니다. 커서를 확보한 후에는 QDesignerFormWindowCursorInterface::setProperty() 함수를 사용하여 상태 속성을 설정할 수 있습니다.

    accept();
}

마지막으로 QEvent::accept() 함수를 호출하여 이벤트 객체의 accept 플래그를 설정합니다. accept 매개변수를 설정하면 이벤트 수신자가 해당 이벤트를 수신하고자 함을 나타냅니다. 원치 않는 이벤트는 상위 위젯으로 전파될 수 있습니다.

TicTacToe 클래스 정의

TicTacToe 클래스는 사용자가 틱택토 게임을 즐길 수 있게 해주는 사용자 정의 위젯입니다.

class TicTacToe : public QWidget
{
    Q_OBJECT
    Q_PROPERTY(QString state READ state WRITE setState)

public:
    explicit TicTacToe(QWidget *parent = nullptr);

    QSize minimumSizeHint() const override;
    QSize sizeHint() const override;
    void setState(const QString &newState);
    QString state() const;
    void clearBoard();

protected:
    void mousePressEvent(QMouseEvent *event) override;
    void paintEvent(QPaintEvent *event) override;

private:
    static constexpr char16_t Empty = '-';
    static constexpr char16_t Cross = 'X';
    static constexpr char16_t Nought = 'O';

    QRect cellRect(int position) const;
    int cellWidth() const { return width() / 3; }
    int cellHeight() const { return height() / 3; }

    QString myState;
    int turnNumber = 0;
};

TicTacToe 클래스 정의에서 주목해야 할 주요 사항은 state 속성의 선언과, 이에 연결된 state() 및 setState() 함수입니다.

TicTacToe 위젯의 상태를 속성으로 선언해야만 Qt Widgets Designer 에서 이를 인식할 수 있습니다. 이를 통해 Qt Widgets Designer 는 TicTacToe 위젯이 QWidget 및 QObject 에서 상속받은 속성을 관리하는 방식과 동일하게 이 상태를 관리할 수 있게 되며, 예를 들어 속성 편집기 기능을 활용할 수 있습니다.

예제 프로젝트 @ code.qt.io

© 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.