Qt Widgets Designerでカスタムウィジェットを作成する

Qt Widgets Designerのプラグイン・ベース・アーキテクチャにより、ユーザ定義ウィジェットやサードパーティ製カスタムウィジェットを標準Qtウィジェットと同様に編集することができます。ウィジェットのプロパティ、シグナル、スロットなど、カスタムウィジェットのすべての機能がQt Widgets Designerで利用できます。Qt Widgets Designerは、フォーム設計プロセスで実際のウィジェットを使用するため、カスタムウィジェットはプレビュー時と同じように表示されます。

QtDesigner モジュールは、Qt Widgets Designer でカスタムウィジェットを作成する機能を提供します。

はじめに

カスタムウィジェットを Qt Widgets Designer に統合するには、ウィジェットの適切な説明と適切なプロジェクトファイルが必要です。

インターフェイス記述の提供

提供したいウィジェットのタイプをQt Widgets Designerに通知するには、ウィジェットが公開するさまざまなプロパティを記述するQDesignerCustomWidgetInterface のサブクラスを作成します。プラグインの作者だけがこの情報を提供できるため、これらのほとんどはベースクラスの純粋な仮想関数によって提供されます。

関数戻り値の説明
name()ウィジェットを提供するクラスの名前。
group()ウィジェットが属する Qt Widgets Designer のウィジェット・ボックスのグループ。
toolTip()Qt Widgets Designerでウィジェットを識別するための短い説明。
whatsThis()Qt Widgets Designerのユーザのためのウィジェットの長い説明。
includeFile()このウィジェットを使用するアプリケーションに含める必要があるヘッダーファイル。この情報は UI ファイルに保存され、uic がカスタムウィジェットを含むフォーム用に生成するコードに適切な#includes ステートメントを作成するために使用されます。
icon()Qt Widgets Designerのウィジェットボックスでウィジェットを表すために使用できるアイコン。
isContainer()ウィジェットが子ウィジェットを保持するために使用される場合は true、そうでない場合は false。
createWidget()カスタムウィジェットのインスタンスへのQWidget ポインタ。

注: createWidget() は、ウィジェットの作成のみを行うファクトリ関数です。カスタムウィジェットのプロパティは、load() が返されるまで利用できません。

domXml()オブジェクト名、サイズヒント、その他の標準QWidget プロパティなど、ウィジェットのプロパティの説明。
codeTemplate()この関数は、Qt Widgets Designer で将来使用するために予約されています。

他の2つの仮想関数も再実装できます:

initialize()カスタムウィジェットの拡張機能とその他の機能を設定します。カスタムコンテナの拡張機能 (QDesignerContainerExtension を参照) とタスクメニューの拡張機能 (QDesignerTaskMenuExtension を参照) は、この関数で設定します。
isInitialized()ウィジェットが初期化されていれば true を返し、初期化されていなければ false を返します。そうでない場合は false を返します。再実装では通常、initialize() 関数が呼び出されたかどうかをチェックし、このテストの結果を返します。

domXml() 関数に関する注意事項

domXml() 関数は、Qt Widgets Designer のウィジェットファクトリーがカスタムウィジェットとその適用プロパティを作成するために使用する UI ファイルスニペットを返します。

Qt 4.4以降、Qt Widgets Designerのウィジェットボックスでは、1つのカスタムウィジェットを記述するための完全なUIファイルを使用できます。UIファイルは、<ui> タグを使用して読み込むことができます。<ui>タグを指定すると、カスタムウィジェットの追加情報を含む<customwidget>要素を追加できます。追加情報が必要ない場合は、<widget> タグで十分です。

カスタムウィジェットが適切なサイズのヒントを提供しない場合、サブクラスのdomXml() 関数が返す文字列でデフォルトのジオメトリを指定する必要があります。例えば、Custom Widget Plugin の例で提供されているAnalogClockPlugin では、以下のようにデフォルトの widgetgeometry を定義しています:

    ...
R"(
    <property name="geometry">
      <rect>
        <x>0</x>
        <y>0</y>
        <width>100</width>
        <height>100</height>
      </rect>
    </property>
")
    ...

domXml() 関数の追加機能として、空の文字列を返した場合、そのウィジェットは Qt Widgets Designer のウィジェット・ボックスにインストールされません。ただし、フォーム内の他のウィジェットで使用することはできます。この機能は、ユーザが明示的に作成する必要はないが、他のウィジェットが必要とするウィジェットを非表示にするために使用します。

完全なカスタムウィジェットの仕様は次のようになります:

<ui language="c++"> displayname="MyWidget">
    <widget class="widgets::MyWidget" name="mywidget"/>
    <customwidgets>
        <customwidget>
            <class>widgets::MyWidget</class>
            <addpagemethod>addPage</addpagemethod>
            <propertyspecifications>
                <stringpropertyspecification name="fileName" notr="true" type="singleline"/>
                <stringpropertyspecification name="text" type="richtext"/>
                <tooltip name="text">Explanatory text to be shown in Property Editor</tooltip>
            </propertyspecifications>
        </customwidget>
    </customwidgets>
</ui>

<ui> タグの属性:

属性プレゼンスコメント
language任意"c++", "jambi"この属性は、カスタムウィジェットの言語を指定します。主に、C++ プラグインが Qt Jambi に表示されるのを防ぐために存在します。
displaynameオプションクラス名この属性の値はWidgetボックスに表示され、名前空間を取り除くために使用できます。

<addpagemethod> タグは、Qt Widgets Designer とuicに、コンテナウィジェットにページを追加する際に使用するメソッドを伝えます。これは、親を渡して子を追加するのではなく、特定のメソッドを呼び出して子を追加する必要があるコンテナウィジェットに適用されます。特に、これは Qt Widgets Designer で提供されるコンテナのサブクラスではなく、Current Page の概念に基づくコンテナに関連します。さらに、それらのコンテナ用にコンテナ拡張機能を提供する必要があります。

<propertyspecifications> 要素には、プロパティのメタ情報のリストを含めることができます。

<tooltip> タ グ を用いて、 プ ロ パテ ィ の上にカー ソ ルを置 く と Property Editor に表示 さ れ る ツールチ ッ プを指定す る こ と がで き ます。プロパティ名は属性name で与えられ、要素テキストはツールチップです。この機能は Qt 5.6 で追加されました。

文字列型のプロパティの場合、<stringpropertyspecification> タグを使用することができます。このタグには以下の属性があります:

属性存在コメント
name必須プロパティの名前
type必須以下の表を参照属性の値は、プロパティエディタがそれらをどのように扱うかを決定します。
notr任意"true", "false"属性が "true "の場合、値は翻訳されることを意図していません。

文字列プロパティのtype 属性の値:

タイプ
"richtext"リッチテキスト。
"multiline"複数行プレーンテキスト。
"singleline"単一行のプレーン・テキスト
"stylesheet"CSSスタイルシート。
"objectname"オブジェクト名(有効な文字数に制限あり)。
"url"URL、ファイル名。

プラグインの要件

プラグインがすべてのプラットフォームで正しく動作するためには、Qt Widgets Designer で必要なシンボルを確実にエクスポートする必要があります。

まず、Qt Widgets Designerでプラグインを読み込むためには、プラグインクラスをエクスポートする必要があります。これにはQ_PLUGIN_METADATA() マクロを使用します。また、QDESIGNER_WIDGET_EXPORT マクロを使用して、Qt Widgets Designer がインスタンス化するプラグイン内の各カスタム・ウィジェット・クラスを定義する必要があります。

お行儀の良いウィジェットの作成

カスタムウィジェットの中には、Qt Widgets Designerの標準ウィジェットとは異なる動作をする特殊なユーザーインターフェイス機能を持つものがあります。具体的には、カスタムウィジェットがQWidget::grabKeyboard() を呼び出した結果としてキーボードを掴んだ場合、Qt Widgets Designer の動作に影響を与えます。

Qt Widgets Designerでカスタムウィジェットに特別な動作をさせるには、initialize()関数の実装を提供し、Qt Widgets Designer固有の動作のためにウィジェット構築プロセスを構成します。この関数は、createWidget() を呼び出す前に最初に呼び出され、Qt Widgets Designer がプラグインの createWidget() 関数を呼び出すときに後でテストできる内部フラグを設定できます。

プラグインのビルドとインストール

単純なプラグイン

Custom Widget Pluginは、シンプルなQt Widgets Designerプラグインです。

プラグインのプロジェクトファイルは、カスタムウィジェットとプラグインインターフェースの両方のヘッダーとソースを指定する必要があります。通常、このファイルは、プラグインのプロジェクトがライブラリとしてビルドされ、Qt Widgets Designerの特定のプラグインがサポートされることを指定するだけです。CMake の場合、これは以下の宣言で行います:

find_package(Qt6 REQUIRED COMPONENTS Core Gui UiPlugin Widgets)

qt_add_plugin(customwidgetplugin)
target_sources(customwidgetplugin PRIVATE
    analogclock.cpp analogclock.h
    customwidgetplugin.cpp customwidgetplugin.h
)
target_link_libraries(customwidgetplugin PUBLIC
    Qt::Core
    Qt::Gui
    Qt::UiPlugin
    Qt::Widgets
)

リンクライブラリのリストでは、Qt::UiPlugin を指定します。これは、プラグインが抽象インターフェースQDesignerCustomWidgetInterfaceQDesignerCustomWidgetCollectionInterface のみを使用し、Qt Widgets Designer ライブラリへのリンクがないことを示します。リンクを持つQt Widgets Designerの他のインターフェースにアクセスする場合は、代わりにDesigner 。これにより、プラグインがQt Widgets Designerのライブラリに動的にリンクされ、実行時に依存することが保証されます。

また、プラグインが他のQt Widgets Designerウィジェット・プラグインと一緒にインストールされていることを確認する必要があります:

   set(INSTALL_EXAMPLEDIR "${QT6_INSTALL_PREFIX}/${QT6_INSTALL_PLUGINS}/designer")
install(TARGETS customwidgetplugin
    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

qmake の場合:

CONFIG      += plugin
TEMPLATE    = lib
HEADERS     = analogclock.h \
              customwidgetplugin.h
SOURCES     = analogclock.cpp \
              customwidgetplugin.cpp
OTHER_FILES += analogclock.json

QT 変数にはキーワードuiplugin が含まれており、これはQt::UiPlugin ライブラリと同等である。

また、プラグインが他のQt Widgets Designerウィジェット・プラグインと一緒にインストールされていることを確認する必要があります:

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

$[QT_INSTALL_PLUGINS] 変数は、インストールされている Qt プラグインの場所を示すプレースホルダです。アプリケーションを実行する前にQT_PLUGIN_PATH 環境変数を設定することで、他の場所にあるプラグインを探すように Qt Widgets Designer を設定できます。

注意: Qt Widgets Designer はdesigner のサブディレクトリを探します。

Qtアプリケーションでライブラリやプラグインのパスをカスタマイズする方法については、QCoreApplication::libraryPaths() を参照してください。

プラグインが Qt Widgets Designer と互換性のないモードでビルドされている場合、プラグインはロードおよびインストールされません。プラグインの詳細については、Plugins HOWTOドキュメントを参照してください。

プラグインの分割

上記で説明した単純なアプローチでは、Qt Widgets Designerの他のインターフェイスを使用する場合に特に問題が発生します:カスタムウィジェットを使用するアプリケーションは、Qt Widgets Designerのヘッダとライブラリに依存することになります。実際のシナリオでは、これは望ましくありません。

次のセクションでは、これを解決する方法を説明します。

アプリケーションへのウィジェットのリンク

qmake を使用する場合、インクルード用の.pri ファイルを作成することで、カスタムウィジェットのソースとヘッダファイルをアプリケーションと Qt Widgets Designer の間で共有することができます:

INCLUDEPATH += $$PWD
HEADERS += $$PWD/analogclock.h
SOURCES += $$PWD/analogclock.cpp

このファイルは、プラグインとアプリケーションの.pro ファイルにインクルードされます:

include(customwidget.pri)

CMake を使用する場合、ウィジェットのソースファイルも同様にアプリケーションプロジェクトに追加できます。

ライブラリを使用してウィジェットを共有する

もう1つの方法は、Qt Widgets Designerプラグインとアプリケーションにリンクされるライブラリにウィジェットを置くことです。実行時にライブラリの場所を特定する問題を避けるために、静的ライブラリを使用することを推奨します。

共有ライブラリについては、共有ライブラリの作成 を参照してください。

QUiLoaderでプラグインを使用する

QUiLoader にカスタムウィジェットを追加する好ましい方法は、QUiLoader::createWidget() を再実装してサブクラス化することです。

しかし、Qt Widgets Designerのカスタムウィジェットプラグインを使用することも可能です(QUiLoader::pluginPaths ()および関連関数を参照)。Qt Widgets Designerライブラリをターゲットデバイスにデプロイする必要がないように、これらのプラグインはQt Widgets Designerライブラリにリンクされていない必要があります(QT = uipluginCreating Custom Widgets for Qt Widgets Designer#BuildingandInstalling thePlugin を参照してください)。

Qt Widgets Designerでカスタムウィジェットを使用する詳細については、Custom Widget Pluginと Task Menu Extensionの例を参照してください。また、QDesignerCustomWidgetCollectionInterface クラスを使用すると、複数のカスタムウィジェットを 1 つのライブラリにまとめることができます。

©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。