コンテナ拡張機能の例
Qt Widgets Designer 用のカスタムマルチページプラグインの作成。
「コンテナ拡張機能」の例では、QDesignerContainerExtension クラスを使用して、Qt Widgets Designer 用のカスタムマルチページプラグインを作成する方法を示します。
Qt Widgets DesignerのUIエディタのスクリーンショット。オブジェクトに対して、現在のページの直前にページを挿入するオプションが表示されている。" src="images/containerextension-example.webp" title="Qt Widgets DesignerのUIエディタのスクリーンショット。オブジェクトに対して、現在のページの直前にページを挿入するオプションが表示されている。"/>
Qt Widgets Designer で使用できるカスタムウィジェットを提供するには、自己完結型の実装を用意する必要があります。この例では、コンテナ拡張機能を示すために設計されたカスタムマルチページウィジェットを使用します。
拡張機能とは、Qt Widgets Designer の動作を変更するオブジェクトのことです。QDesignerContainerExtension を使用することで、Qt Widgets Designer はカスタムマルチページウィジェットの管理や操作(ウィジェットへのページの追加や削除など)を行うことができます。
Qt Widgets Designer では、4 種類の拡張が利用可能です:
- QDesignerMemberSheetExtension Qt Widgets Designer のシグナルおよびスロット編集モードを使用して接続を設定する際に表示される、ウィジェットのメンバ関数を操作できる拡張機能を提供します。
- QDesignerPropertySheetExtension Qt Widgets Designer のプロパティエディタに表示され、ウィジェットのプロパティを操作できる拡張機能を提供します。
- QDesignerTaskMenuExtension Qt Widgets Designer のタスクメニューにカスタムメニュー項目を追加できる拡張機能を提供します。
- QDesignerContainerExtension Qt Widgets Designer のマルチページコンテナプラグインにページを追加(および削除)できる拡張機能を提供します。
この例と同じパターンに従って、それぞれの拡張機能のベースクラスを置き換えるだけで、すべての拡張機能を使用できます。詳細については、 Qt Widgets Designer C++ Classesを参照してください。
「コンテナ拡張機能」の例は、4つのクラスで構成されています:
MultiPageWidgetは、ユーザーがページを操作・追加し、コンボボックスを使用してそれらの間を移動できるようにするカスタムコンテナウィジェットです。MultiPageWidgetPluginは、MultiPageWidgetクラスをQt Widgets Designer に公開します。MultiPageWidgetExtensionFactoryは、MultiPageWidgetContainerExtensionオブジェクトを作成します。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()という2つのプライベートスロットを実装する必要があります。 各ページに独自のタイトルを付与できるようにするため、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;
}異なる関数の 1 つは isContainer() 関数であり、この例ではカスタムウィジェットをコンテナとして使用することを想定しているため、true を返します。
bool MultiPageWidgetPlugin::isContainer() const
{
return true;
}もう1つ異なるのは、カスタムウィジェットを作成する関数です:
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 クラスが提供するcore()関数を使用して、現在のQDesignerFormEditorInterface オブジェクトを取得します。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 の現在の拡張機能マネージャーを使用することで、指定されたオブジェクトの拡張機能を取得できます。また、指定されたオブジェクトに対して拡張機能を登録したり、登録を解除したりすることも可能です。拡張機能とは、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;
}ここでは、`Qt Widgets Designer`の`QDesignerFormEditorInterface `パラメータから取得した現在の`extension manager `を使用して登録する`MultiPageWidgetExtensionFactory `オブジェクトを作成します。第1引数は新しく作成されたファクトリ、第2引数は文字列形式の拡張子識別子です。`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 からカスタムマルチページウィジェットの機能にアクセスできるようにすることのみを目的としていることに注意してください。カスタムマルチページウィジェットは、この拡張機能の関数に対応する機能を実装する必要があります。
また、2つの引数(親ウィジェットと、タスクメニューが要求される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.