qt-figma-token-extraction について
Figma からデザイントークンを抽出して QML の型に対応付け、Theme シングルトンを中心とする QML デザインシステムを生成するスキルです。Figma MCP とローカルの curl による抽出に対応します。
主な機能
- 01Figma の変数とスタイルの抽出
- 02トークンの QML 型への対応付け
- 03Theme シングルトンのデザインシステム生成
- 04変数モードとエイリアスへの対応
- 05生成した QML 用の Qt プロジェクト設定
活用シーン
- 01Figma トークンからの QML テーマ作成
- 02色やタイポグラフィの Qt プロジェクトへの移行
- 03複数の Figma ソースからのデザインシステムファイル生成
MCP 対応
Figma MCP ツールで変数を読み取り、デザイントークンを抽出できます。代替手段として、ローカルの curl による抽出手順も記載されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ theqtcompanyrnd/ agent-skills --skill qt-figma-token-extractionインストール後、Claude Code で/qt-figma-token-extractionを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
examples/FontInterface.qmlPrimitives.qmlSpacing.qmlTheme.qmlTypography.qmlreferences/token-mapping.md詳細
Figma トークン抽出スキル
このスキルは、Figma ファイルからデザイントークンを抽出して QML 型に対応付け、統一された Theme シングルトンを備えた、すぐに使える QML デザインシステムを生成します。
スキルの構成
サポートファイルは、この SKILL.md と一緒に読み込まれます。
qt-figma-token-extraction/
├── SKILL.md # this file — entry point
├── references/
│ └── token-mapping.md # Figma variable type → QML type mapping rules
└── examples/
├── Primitives.qml # primitive color palette template
├── Theme.qml # semantic token template (references Primitives)
├── FontInterface.qml # font loaders + icon index template
├── Spacing.qml # spacing and radii template
└── Typography.qml # typography scale template
ステップ 4(型のマッピング)に進む際は、QML を生成する前に references/token-mapping.md を読んでください。
ステップ 6 で QML ファイルを生成する際は、構造のテンプレートとして examples/ 内のファイルを使用してください。これらのファイルは、Qt Design Studio の実際の命名規則と構成パターンを反映しています。
ステップ 0 — Qt プロジェクトのセットアップを確認する
プロジェクトが開いているように見える場合でも、必ず AskUserQuestion ツールを呼び出してください。現在開いているプロジェクトが対象だと決めつけないでください。
呼び出す前に、質問を適切なものにするため、コンテキストを確認してください。
- プロジェクトがすでに開いている(ファイルが表示されている、
CMakeLists.txtが存在する)場合は、ユーザーが確認または変更できるよう、最初の選択肢にそのプロジェクト名を含めてください。 - ユーザーの依頼が更新(「色を更新」「トークンを再抽出」「デザインシステムを同期」など)の場合は、「新しいプロジェクトを作成する」という選択肢を省略してください。更新では常に既存のプロジェクトを対象とします。
更新依頼の場合 — 「新規作成」を含めず、2 つの選択肢を提示します。
tool: AskUserQuestion
question: "Which project should I update the design tokens in?"
options:
- "This project — <detected project name or path> (currently open)"
- "A different existing project — I'll give you the path"
初回セットアップ依頼の場合 — 3 つすべての選択肢を提示します。
tool: AskUserQuestion
question: "Which Qt project should I set up the design system in?"
options:
- "This project — <detected project name or path> (currently open)"
- "A different existing project — I'll give you the path"
- "Create a new project"
プロジェクトがまだ開いていない場合は、最初の選択肢を "既存のプロジェクト — パスを指定します" のみに置き換えてください。
プロジェクトが存在する場合(確認済み、またはパスが指定された場合): プロジェクトのパスを記録します。ステップ 1 に進んでください。まだ Figma ファイルについて尋ねないでください。
新しいプロジェクトが必要な場合: フォルダー構成を作成し、main.cpp と main.qml を作成してから、ステップ 1 に進みます。
my-project/
├── CMakeLists.txt ← set up in Step 7
├── main.cpp ← create now (template below)
├── main.qml ← create now (template below)
└── design-system/ ← generated files go here
main.cpp は次の内容をそのまま使用して作成してください。Qt Quick では Widgets は不要なので、QApplication ではなく QGuiApplication を使用してください。
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.loadFromModule("<ProjectName>", "Main");
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
<ProjectName> は qt_add_qml_module() で使用する URI に置き換えてください。両者は完全に一致している必要があります。
以前の
QUrl url(u"qrc:/..."_qs)パターンは使用しないでください。 Qt 6 では、qt_add_qml_moduleによってファイルはqrc:/qt/qml/<URI>/の下に配置されます。Qt 5 のようなqrc:/<URI>/ではありません。以前のパスを使用すると、エラーが表示されないまま読み込みに失敗します。loadFromModule()を使えばこの問題を完全に回避でき、Qt 6.5 以降で正しい方法です。
プレースホルダーとして Main.qml を作成してください。小文字の m ではなく、大文字の M にします。loadFromModule() は大文字と小文字を区別し、Main という名前の型を探すため、これは Main.qml に対応します。
import QtQuick
Window {
width: 640
height: 480
visible: true
title: "My Qt App"
}
CMake のセットアップ: シングルトン登録を含む完全な CMakeLists.txt は、すべての QML ファイルが確定するステップ 7 で作成します。今は作成しないでください。ユーザーがビルド設定の問題に遭遇した場合は、ここでトラブルシューティングを行うのではなく、Qt の CMake ドキュメント(https://doc.qt.io/qt-6/cmake-get-started.html)を確認するよう案内してください。
ステップ 1 — 振り分けの質問
以下の質問ごとに、AskUserQuestion ツールを 1 つずつ呼び出してください。現在のインターフェースで AskUserQuestion ツールを利用できない場合は、同じ質問を通常のテキストで尋ね、回答を待ってから続行してください。まだ Figma のリンクを尋ねないでください。
呼び出し 1 — モード:
tool: AskUserQuestion
question: "Does your Figma design system use multiple variable modes?"
options:
- "Yes — for example Light and Dark themes"
- "No — single mode only"
- "I'm not sure"
回答を待ってから、次を尋ねます。
呼び出し 2 — ターミナル:
tool: AskUserQuestion
question: "Are you comfortable running a short command in a terminal on your own computer?"
options:
- "Yes, I can use a terminal"
- "No, I prefer not to use a terminal"
| 回答の組み合わせ | 使用する方法(内部用) |
|---|---|
| 単一モード/「わからない」+ターミナルに関する任意の回答 | MCP 方式 — 抽出時にモードを確認し、必要に応じて対応します |
| 複数モード+ターミナルの使用に抵抗がない | curl 方式 — 1 つのコマンドですべてのモードを取得します |
| 複数モード+ターミナルの使用に抵抗がある | MCP 方式(モードを手動で切り替えます) |
モードについて「わからない」と回答した場合は、MCP を使って進め、抽出中にモードを確認してください。最初から説明するのではなく、確認した後で内容を説明します。
ファイルが Variables を使用しているか Styles を使用しているかは尋ねないでください。 ステップ 2 で Figma ファイルの URL を受け取った後に自動検出し、
get_variable_defsを呼び出すかファイルを調べて、確認結果を報告してください。Variables がある場合は Variables 抽出を、Styles のみがある場合は Styles 抽出を、両方がある場合は両方の抽出を使用してください。
ステップ 2 — すべての Figma ファイルのリンクを収集する
抽出方法がわかったら、抽出を始める前に、Figma ファイルの URL をすべてまとめて尋ねます。これにより、後でワークフローを中断せずに済みます。
ユーザーに尋ねます。
「デザイントークンを含む Figma ファイルの URL をすべて共有してください。トークンが複数のファイルやページに分かれている場合(例:色は一方のファイル、タイポグラフィは別のファイル)、今すべて共有し、それぞれのファイルに何が含まれているか教えてください。」
先に進む前に、URL をすべて受け取ります。各 URL からファイルキーを抽出します。これは、/design/ と次の / の間にある英数字の文字列です。各ファイル/ページに含まれるトークンの種類を記録します。
コミュニティファイルに関する注意: ユーザーが自分のアカウントに複製していない Figma コミュニティファイルの URL が含まれている場合は、ここで注意を促します。抽出ツールはコミュニティファイルに直接アクセスできません。まず Figma でファイルを自分のドラフトに複製し(ファイルを開く → ドラフトに複製)、新しい URL を共有するよう依頼します。
MCP の方法 — Figma MCP による抽出
(使用する場合:シングルモードのシステム、またはユーザーがターミナルに慣れていない場合)
必要条件: Figma MCP が接続されていること。パーソナルアクセストークンやローカルでのセットアップは不要です。
注: この方法で読み取るのは、現在 Figma でアクティブな変数モードのみです。デザインシステムに複数のモード(例:ライト/ダーク)がある場合、読み取りのたびにユーザーが Figma でモードを切り替える必要があります。実行可能ですが、手順が増えます。この制限は最初に説明しないでください。抽出中に複数のモードが見つかった場合にのみ説明します。
ステップ 1a — Figma MCP の接続を確認する
何かを始める前に、Figma MCP のツールが利用可能であることを確認します。変数の抽出、デザインコンテキストの読み取り、またはファイルメタデータを示す名前のツールを探してください。Figma MCP サーバーによって正確な名前は異なる場合があります(例:get_variable_defs、getVariableDefinitions、figma_get_variables)。このスキルに記載されているツール名は例であり、固定の仕様ではありません。名前の文字列そのものではなく、目的に基づいて判断してください。
Figma のツールがまったく利用できない場合は、ユーザーに次のように伝えます。
「Figma MCP コネクターがまだ接続されていません。Claude のインターフェイス(Settings → Connectors または MCP configuration)で接続してから、戻ってきてください。そこから開始できます。」
接続が確認されるまで先に進まないでください。
ステップ 1b — モードを確認する
ファイルノード ID を指定して get_variable_defs を呼び出し、どのコレクションとモードがあるかを確認します。
Tool: get_variable_defs
Input: { "nodeId": "<root node id or specific variable group node id>" }
応答に複数のモードが示され、ユーザーがすべてのモードを希望する場合は、読み取りのたびに Figma でモードを切り替えてもらう必要があることを説明してから、続行します。
ステップ 1c — 変数を抽出する
該当するノードで get_variable_defs を呼び出します。トークンのカテゴリ(色、タイポグラフィ、間隔、角丸、シャドウ)ごとに、一度に 1 つのコレクションを処理します。各コレクションについて、アクティブなモードの値を読み取ります。
複数のモードを取得する必要がある場合:
- 現在のモードの値をすべて抽出して記録します
- Figma でアクティブなモードを切り替えるようユーザーに依頼します(View メニュー → Variable Modes、またはキャンバス上のモードスイッチャー)
- 再度
get_variable_defsを呼び出し、新しいモードの値を記録します - 各モードについて繰り返します
- モードキーを使って、1 つのトークンファイルにまとめます(ステップ 5 の出力形式を参照)
ステップ 1d — エイリアスを解決する
変数値が別の変数を参照している場合(エイリアス)、最終的な値まで解決します。解決されていないエイリアス参照を出力ファイルに書き込まないでください。解決できないものにはフラグを付け、ユーザーに確認してください。
curl メソッド — ユーザーのローカルマシンからの抽出
(使用する場面:複数の可変モードがあり、ユーザーがターミナルの操作に慣れている場合)
必要なもの: ターミナルへのアクセス(curl は macOS と Linux に標準搭載されており、Windows 10 以降でも利用できます)、および Figma Personal Access Token(viewer スコープで十分です)。
重要: curl コマンドを実行する前に、このセクションのすべての手順、特に PAT の設定と検証を完了してください。無効なトークンで curl を実行すると、壊れた出力ファイルが作成されます。
コミュニティファイルはサポートされていません。 curl コマンドは、ユーザー自身のアカウントにある Figma ファイル(所有しているファイル、または招待されたファイル)でのみ動作します。閲覧中でも複製していないコミュニティファイルでは、403 エラーが返されます。ユーザーがコミュニティファイルを使用している場合は、まず自分のアカウントに複製するよう案内してください。Figma でコミュニティファイルを開き → 下書きに複製をクリックし → 複製したファイルの URL を使用します。
ステップ 1a — Figma Personal Access Token を設定する
何よりも先に行います。ユーザーに確認してください。
「抽出コマンドを実行する前に、Figma Personal Access Token が必要です。すでにお持ちですか?」
持っている場合:検証(ステップ 1b)に進みます。
持っていない場合は、作成手順を案内します。
- ブラウザーまたはデスクトップアプリで Figma を開きます
- アバター(左上)をクリック → 設定
- セキュリティタブを開きます
- Personal access tokens までスクロール → Generate new token をクリックします
- 任意の名前(例:「Claude token export」)を付け、スコープを Viewer に設定します
- トークンをすぐにコピーします。Figma で表示されるのは一度だけです
ステップ 1b — 続行する前に PAT の動作を確認する
PAT が最近(過去 90 日以内に)検証済みの場合は、この手順をスキップできます。それ以外の場合は、ターミナルで次の検証コマンドを実行するようユーザーに依頼してください。
curl -H "X-Figma-Token: YOUR_TOKEN" "https://api.figma.com/v1/me"
期待される結果:Figma アカウントのメールアドレスを含む JSON 応答(例:"email": "[email protected]")。
応答に "status": 403 または "Invalid token" が含まれている場合、トークンが間違っているか、期限切れです。新しいトークンを生成して再試行するようユーザーに依頼してください。検証が成功するまで、抽出に進まないでください。
ステップ 1c — 変数の抽出を実行する
ターミナルで次を実行するようユーザーに依頼してください。
curl -H "X-Figma-Token: YOUR_TOKEN" "https://api.figma.com/v1/files/FILE_KEY/variables/local" -o design-tokens-raw.json
これにより、すべてのコレクション、すべてのモード、すべての値を含む完全な未加工の変数エクスポートが design-tokens-raw.json に保存されます。
ステップ 1d — 結果を共有する
コマンドの完了後、ユーザーに次のいずれかを依頼してください。
design-tokens-raw.jsonを会話にアップロードする- ファイルの内容を会話に貼り付ける
その後、以下のステップ 2(テキストスタイル)に進みます。
スタイルを抽出する
注: Figma Styles(テキスト、カラー、エフェクト)は Variables とは別に保存されており、独自の抽出手順が必要です。ユーザーのデザインシステムで Variables ではなく Styles を主なトークンソースとしている場合、この手順が二次的なものではなく、主な抽出手順になります。デザインシステムで Variables と Styles の両方を使用している場合は、まずステップ 1 を完了してから、この手順を行ってください。
ページごとの手順: Figma ファイルでは、トークンの種類が複数のページに分散していることがよくあります(例:あるページにカラー、別のページにタイポグラフィ)。すべてを一度に抽出しようとしないでください。どのページにどの種類のトークンがあるかをユーザーに尋ね、一度に 1 ページずつ抽出してください。次のページに進む前に、各ページで見つかった内容を確認してください。
MCP メソッド — テキストスタイル
デザインシステムのテキストスタイルを使用しているテキストフレームまたはコンポーネントに対して get_design_context を使用します。見出し、本文、ラベルなど、代表的なテキスト要素を含むフレームを Figma で選択して読み取るよう、ユーザーに依頼してください。
Tool: get_design_context
Input: { "fileKey": "<key>", "nodeId": "<selected text frame node id>" }
応答から、各テキストスタイルについて、スタイル名、フォントファミリー、フォントサイズ、フォントウェイト、行の高さ、文字間隔を抽出します。すべてのテキストロール(H1~H6、本文、ラベル、キャプション、コード)を確認してください。1 つのフレームですべてを確認できない場合は、追加のフレームを選択するようユーザーに依頼してください。
curl メソッド — テキストスタイル
テキストスタイルには、curl 呼び出しが 2 回必要です。1 回目でノード ID を含むスタイル一覧を取得し、2 回目でそれらのノードの実際のプロパティ値を取得します。Step 1a の PAT はすでに検証済みなので、そのまま進めてください。
curl -H "X-Figma-Token: YOUR_TOKEN" "https://api.figma.com/v1/files/FILE_KEY/styles" -o text-styles-list.json
次に、text-styles-list.json から node_id の値を抽出してカンマでつなぎ、以下を実行します。
curl -H "X-Figma-Token: YOUR_TOKEN" "https://api.figma.com/v1/files/FILE_KEY/nodes?ids=NODE_IDS" -o text-styles-nodes.json
text-styles-nodes.json から、各テキストスタイルのフォントファミリー、フォントサイズ、フォントウェイト、行の高さ、文字間隔、および適用されているテキスト装飾やテキスト変換を抽出します。
コマンドの実行が完了したら、両方のファイルを会話にアップロードするか、内容を貼り付けるようユーザーに依頼してください。
テキストスタイルをトークンファイルにマージする
テキストスタイルは、design-tokens.json の typography セクションにマージします。変数ベースのタイポグラフィトークンと区別するため、"source": "textStyle" を設定してください。
"typography": {
"fontFamilyHeading": { "value": "Titillium Web", "figmaName": "Font/Heading", "type": "STRING", "source": "variable" },
"h1Size": { "value": 36, "unit": "px", "figmaName": "H1/Size", "type": "FLOAT", "source": "variable" },
"h1": {
"figmaName": "Heading/H1",
"source": "textStyle",
"fontFamily": "Titillium Web",
"fontSize": 36,
"fontWeight": 600,
"lineHeight": 54,
"letterSpacing": 0
},
"bodyDefault": {
"figmaName": "Body/Default",
"source": "textStyle",
"fontFamily": "Inter",
"fontSize": 14,
"fontWeight": 400,
"lineHeight": 22,
"letterSpacing": 0
}
}
デザインシステムがテキストスタイルだけでタイポグラフィを定義している場合(タイポグラフィ変数がない場合)、source: "variable" のエントリーは存在しません。それで問題ありません。テキストスタイルだけで十分です。
Step 3 — 生データを確認する
どちらの方法を使った場合も、命名規則を適用する前に、ユーザーと一緒に生のトークンデータを確認します。
- すべてのファイルを抽出済み: ユーザーが挙げたファイルがすべて抽出されていることを確認します。欠けているファイルがある場合は、先に進まないでください。
- コレクションの存在: コレクション名は、各ファイルについてユーザーが想定しているものと一致していますか?
- モードの取得: 複数のモードがある場合、すべてのモードが正しい値とともに表示されていることを確認します。
- 色の値: いくつかの 16 進数値を Figma ファイルと照合して確認します。
- エイリアスの解決: プリミティブを参照するセマンティックトークンは、値が解決されている必要があります。エイリアスを解決できない場合、参照先のプリミティブがまだ抽出されていないファイルに存在する可能性が非常に高いです。続行する前に、そのファイルに戻って抽出してください。
- 不足しているコレクション: 想定していたものがない場合は、どの Figma ファイルにあるかユーザーに尋ね、インベントリに追加します。
Step 4 — トークンの種類を割り当て、命名規則を適用する
QML を生成する前に、必ず references/token-mapping.md を読み、Figma の各変数タイプに対応する正しい QML 型(COLOR → color、FLOAT → int または real、STRING → string など)を確認してください。 生成するすべてのファイルで、このマッピングを一貫して適用します。
既存の命名規則があるかユーザーに尋ねます。ない場合は、以下の Qt Design Studio の規則を使い、確認してください。
| トークンタイプ | 規則 | 例 |
|---|---|---|
| プリミティブカラー | {family}_{scale} | neutral_900、neon_500 |
| プリミティブグループ | ファミリーごとにネストした QtObject | Primitives.neutrals.neutral_900 |
| セマンティックカラー | {role}_{variant} | background_default、text_muted |
| セマンティックグループ | Theme シングルトンにフラットに配置 | Theme.background_default |
| セマンティックバリアント | _default / _muted / _subtle | stroke_strong、stroke_muted、stroke_subtle |
| 通知トークン | notification_{type}_{variant} | notification_alert_default、notification_danger_muted |
| 間隔の段階 | x{multiplier} | x4(= 8 px)、x8(= 16 px) |
| 角丸の半径 | radius_{size} | radius_s、radius_m、radius_full |
| フォントローダー | 説明的なコンポーネント名 | interFont、titilliumSemiBold、inconsolata |
| アイコン名 | {icon_name}_{size} | close_16、settings_fill_16 |
すべての名前に snake_case を使用します。元の Figma 名は、常に design-tokens.json の figmaName フィールドに保持します。
JSON と QML の命名規則: これらの規則は、生成する QML 出力に適用されます。JSON との互換性を保つため、
design-tokens.jsonではトークンキーを camelCase(例:backgroundPrimary、cornerRadiusM)で保存します。QML を生成する Step 6 でsnake_caseに変換します。
ステップ 5 — design-tokens.json を作成する
抽出したすべてのファイルを統合した design-tokens.json を 1 つ作成します。別々の Figma ファイルに含まれるプリミティブトークンとセマンティックトークンは、別々のセクションに保持します。これにより、2 層構造が保たれ、各トークンがどのレイヤーに属するかが明確になります。単一モードのトークンではフラットな value フィールドを使用し、複数モードのトークンでは modes の下に値をネストします。
{
"meta": {
"extractedAt": "<ISO 8601 timestamp>",
"namingConvention": "camelCase (JSON) / snake_case (QML)",
"extractionMethod": "MCP | curl",
"sources": [
{ "figmaFileName": "Global Tokens", "url": "<Figma URL>", "tier": "primitive" },
{ "figmaFileName": "Design Tokens", "url": "<Figma URL>", "tier": "semantic" }
]
},
"_comment_primitives": "Raw values from the Global Tokens file — the building blocks",
"colors": {
"neutral000": { "value": "#ffffff", "figmaName": "Neutral/000", "type": "COLOR" },
"neon600": { "value": "#1f9b5d", "figmaName": "Neon/600", "type": "COLOR" }
},
"_comment_semantic": "Semantic values from the Design Tokens file — reference primitives via resolvedFrom",
"semanticColors": {
"backgroundPrimary": {
"figmaName": "Background/Primary", "type": "COLOR",
"resolvedFrom": "neutral000",
"modes": {
"Light": { "value": "#ffffff" },
"Dark": { "value": "#181818" }
}
}
},
"typography": {
"fontFamilyHeading": { "value": "Titillium Web", "figmaName": "Font/Heading", "type": "STRING" },
"h1Size": { "value": 36, "unit": "px", "figmaName": "H1/Size", "type": "FLOAT" },
"h1Weight": { "value": 600, "figmaName": "H1/Weight", "type": "FLOAT" },
"h1LineHeight": { "value": 54, "unit": "px", "figmaName": "H1/LineHeight", "type": "FLOAT" }
},
"spacing": {
"x4": { "value": 8, "unit": "px", "figmaName": "Spacing/X4", "type": "FLOAT" },
"x8": { "value": 16, "unit": "px", "figmaName": "Spacing/X8", "type": "FLOAT" }
},
"radii": {
"cornerRadiusS": { "value": 4, "unit": "px", "figmaName": "Radius/Small", "type": "FLOAT" },
"cornerRadiusFull": { "value": 9999, "unit": "px", "figmaName": "Radius/Full", "type": "FLOAT" }
},
"shadows": {
"shadowLow": {
"offsetX": 0, "offsetY": 1, "blur": 3, "spread": 0,
"color": "rgba(0,0,0,0.12)", "figmaName": "Shadow/Low"
}
}
}
デザインシステムのプロジェクトフォルダーのルートに保存します。パスをユーザーに確認してください。
ステップ 6 — QML ファイルを生成する
完成した design-tokens.json を信頼できる唯一の情報源として、QML シングルトンファイルを生成します。すべてのファイルを Qt プロジェクトのルートにある design-system/ フォルダーに配置します。
まずアセットテンプレートを読む
QML を書く前に、各出力ファイルに対応するアセットファイルを読みます。これらは準拠すべき正式なテンプレートであり、従うべき正確な構造、命名規則、グループ化、セクション順序を定義しています。
| 出力ファイル | 読み込むサンプル | 内容 |
|---|---|---|
Primitives.qml | examples/Primitives.qml | 色のファミリーごとのネストされた QtObject、{family}_{scale} 形式の命名 |
Theme.qml | examples/Theme.qml | Primitives を参照するフラットなセマンティックトークン、役割ごとのグループ化 |
Spacing.qml | examples/Spacing.qml | x{n} 形式のスペーシング値、radius_{size} 形式の角丸 |
FontInterface.qml | examples/FontInterface.qml | インラインの component フォントローダー、Unicode マッピングを含む Icons QtObject |
Typography.qml | examples/Typography.qml | フォントウェイト定数と、タイプスケールのサイズ/ウェイトの組み合わせ |
各ファイルを生成する直前に、そのファイルのアセットを読みます。以前に読んだアセットの記憶に頼らないでください。
フォルダー構造
design-system/
├── Primitives.qml ← raw color palette (nested by family: neutrals, accents)
├── Theme.qml ← semantic color tokens (references Primitives)
├── Spacing.qml ← spacing steps and corner radii
└── FontInterface.qml ← font loaders + icon unicode index
次の順に生成します。依存関係のない Primitives を最初に、次に独立している Spacing と FontInterface を、最後に Primitives を参照する Theme を生成します。
qmldir を手書きしないでください。 モジュールの登録は CMakeLists.txt の
qt_add_qml_module()が処理します。シングルトンの登録にはset_source_files_propertiesを使用します(ステップ 7 で更新)。
生成ルール
- すべての値は
design-tokens.jsonから取得します。トークンファイルにない値をハードコードしないでください - すべて
snake_caseを使用します。例:background_default、neutral_900、x4、radius_m Primitives.qmlには生の値のみを記述し、セマンティックな意味は持たせません。Theme.qmlにはセマンティックトークンのみを記述し、必ずPrimitivesを参照します。生の 16 進数値は使用しませんreferences/token-mapping.mdの型マッピングを適用します。色にはreadonly property color、サイズにはreadonly property int、フォント名にはreadonly property stringを使用します- すべてのファイルの先頭にソースコメントと CMake に関する注意書きを記述します
- 関連するプロパティをセクションコメント(
// ── Section name ─────)でグループ化します - JSON にトークンがない場合は、値を推測せず
// TODO: <figmaName>のプレースホルダーを残します - インポート:
import QtQuickを使用します。Qt 6 ではimport QtQuick.Windowは冗長です(Window はすでに含まれています)が、追加してもエラーにはなりません - エフェクトとグラデーション:
import QtQuick.EffectsのMultiEffectを使用します(Qt 6.5 以降で利用可能)。Qt5Compat.GraphicalEffectsは使用しないでください。追加の互換モジュールが必要で、すべての Qt 6 構成で利用できるわけではありません - QML コーディングスキル:
qt-development-skills:qt-qmlスキルを利用できる場合は、正しい Qt 6 のパターンを適用できるよう、QML ファイルの生成時に使用してください
ステップ 7 — 確認、QML の修正、CMakeLists.txt の更新
すべての QML ファイルを生成したら、検証を実施します。以下のチェックを一つも省略しないでください。
QML の検証:
// TODO:のプレースホルダーがないか確認します。見つかった場合はユーザーに知らせ、解決方法を尋ねます- すべてのプロパティ型が
references/token-mapping.mdのルールに一致していることを確認します - すべてのファイルに
pragma Singletonとimport QtQuickが含まれていることを確認します - トークンファイルから取得すべき値がハードコードされていないか確認します
CMakeLists.txt — 必須の更新:
このステップの一環として、必ず CMakeLists.txt を更新してください。ユーザーに任せたままにしないでください。ファイルを開き、qt_add_qml_module() ブロックを見つけ、生成されたデザインシステムのファイルがすべて QML_FILES に列挙され、set_source_files_properties に登録されていることを確認します。これは、シングルトンを QML から利用できない場合に最もよくある原因です。
命名規則:
main.cpp内のターゲット名、URI、loadFromModule()の呼び出しには、すべて同じプロジェクト名の文字列を使用する必要があります。project()の CMake 呼び出しに指定された実際のプロジェクト名を使い、MyProjectをそのまま代用しないでください。
cmake_minimum_required(VERSION 3.16)
project(<ProjectName> VERSION 0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Version pin must match qt_standard_project_setup REQUIRES below
find_package(Qt6 6.5 REQUIRED COMPONENTS Quick)
qt_standard_project_setup(REQUIRES 6.5)
# MACOSX_BUNDLE is required on macOS — without it, qt_add_qml_module creates
# a directory named <ProjectName>/ which collides with the linker output file
# (EISDIR error). MACOSX_BUNDLE makes the output MyQtApp.app, no collision.
qt_add_executable(<ProjectName> MACOSX_BUNDLE
main.cpp
)
set_source_files_properties(
design-system/Primitives.qml
design-system/Theme.qml
design-system/Spacing.qml
design-system/FontInterface.qml
PROPERTIES QT_QML_SINGLETON_TYPE TRUE
)
qt_add_qml_module(<ProjectName>
URI <ProjectName>
VERSION 1.0
QML_FILES
Main.qml # capital M — must match loadFromModule("<ProjectName>", "Main")
design-system/Primitives.qml
design-system/Theme.qml
design-system/Spacing.qml
design-system/FontInterface.qml
# NOTE: do NOT add main.cpp here — it belongs only in qt_add_executable()
)
target_link_libraries(<ProjectName> PRIVATE Qt6::Quick)
<ProjectName> はすべて同じ文字列(例:MyQtApp)に置き換えてください。project() の呼び出しと、main.cpp 内の loadFromModule("<ProjectName>", "Main") の呼び出しに一致させます。
CMakeLists.txt を更新した後、ファイルが保存されたことをユーザーに確認し、Main.qml でシングルトンを使用する方法を示します。
import QtQuick // Window is part of QtQuick in Qt 6 — do NOT add import QtQuick.Window
import <ProjectName> // imports all singletons from the module
Window {
visible: true
width: 640
height: 480
color: Theme.background_default
}
CMake の問題: CMakeLists.txt の更新後にビルドエラーが発生した場合は、インラインでトラブルシューティングするのではなく、Qt の CMake ドキュメント(https://doc.qt.io/qt-6/cmake-get-started.html)を確認するようユーザーに提案します。
ステップ 8 — 要約
ユーザーに簡潔な要約を伝え、出力を確認するよう依頼します。
- カテゴリごとに抽出したトークンの合計数(色、スペーシング、タイポグラフィ、角丸)
- 取得したモードとテーマ
- 未解決のエイリアスや、対応が必要な
// TODO:プレースホルダー - 生成したファイル:
design-tokens.json、Primitives.qml、Theme.qml、Spacing.qml、FontInterface.qml - 各シングルトンファイルについて、CMakeLists.txt で
set_source_files_properties(... QT_QML_SINGLETON_TYPE TRUE)を設定する必要があることを再確認 - 見落としがないか確認するため、このファイル末尾のトークンカテゴリチェックリストを使用
- デザインシステムの基盤が整い、コンポーネント生成スキルを開始できることを確認
トークンカテゴリチェックリスト
- プリミティブカラーパレット(すべての色系統とスケール)
- すべてのモードを含むセマンティックカラートークン(存在する場合)
- フォントファミリー(見出し、本文、等幅)
- フォントの太さ(数値:400/500/600/700)
- 変数から取得したタイポグラフィスケール(変数として定義されている場合、役割ごとのサイズ+太さ+行の高さ)
- テキストスタイル(H1~H6、本文、ラベル、キャプション、コード — フォントファミリー、サイズ、太さ、行の高さ、文字間隔)
- スペーシングスケール(基本単位+名前付きの全ステップ)
- 角丸(S、M、L、Full)
- 影/エレベーションレベル(存在する場合)
- アイコンサイズトークン(存在する場合)
- アニメーション/持続時間トークン(存在する場合)