Qt Creator で モデリングをしてみよう

# はじめに

やや遅れてしまいましたが [Qt Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qt) の 8 日目です。
私はオブジェクト指向が好きで、 業務領域の分析や設計時に [UML](https://ja.wikipedia.org/wiki/統一モデリング言語) (Unified Modeling Language) を使ってきました。
Qt でもこれらの作業ができるツール[^1]がないかと探したところ、Qt Creator 上で UML っぽい[^2] 図を作成できるプラグインがあるのでご紹介したいと思います。

# Qt Creator でモデリング？

ここで扱うモデリングは、ソフトウェアの構造や振る舞いなどを（主に）図で表現することを示します。
Qt Creator には、以下のようなモデリング環境が用意されています。

* [ModelEditor](https://doc.qt.io/qtcreator/creator-modeling.html) ： UML (Unified Modeling Language[^3]) っぽい図を用いてモデリングを行うためのプラグインです。
* [ScxmlEditor](https://doc.qt.io/qtcreator/creator-scxml.html) [^4]： 状態遷移図 [^5] を用いて [SCXML](https://www.w3.org/TR/scxml/)  を定義できるプラグインです。この [SCXML](https://www.w3.org/TR/scxml/)  は、[Qt SCXML](https://doc.qt.io/qt-5/qtscxml-index.html) モジュールから利用することができます。

そして、今回は [ModelEditor](https://doc.qt.io/qtcreator/creator-modeling.html) の紹介となります。

# ModelEditor って何ができるの？

* UML に似た図を作成することができます。
* パッケージ図、クラス図、コンポーネント図、ユースケース図、シーケンス図、アクティビティ図、配置図が使えます。
* 複数選択した際、各要素のプロパティを同時に編集することができます。
* 自動色付け、簡単な位置合わせ、ラベルの自動レイアウトにより、数回のクリックで図を書くことができます。
* Qt Creator のプロジェクトエクスプローラーから、ファイルやフォルダーをドラッグするだけでダイアグラムに追加することができます。
* ダイアグラムからソースコードに遷移することができます。
* 独自の要素を追加することができます。
* モデルデータとダイアグラムの情報は、一つの XML 形式のファイルに格納されます。

# まずは準備

1. Qt Creator を起動してください。
2. アップルメニュー > プラグインについて [^6] を選んで「インストール済みプラグイン」ダイアログを表示させます。

![InstalledPlugins.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/c1de93b0-da14-ac1e-15c2-c9685340841e.png)
3. ダイアログ上部の入力欄に「model」 と入力してください。

![InstalledPlugins2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/c30cb613-03a9-1d31-c4c2-a3e55daaf44c.png)
4. ModelEditor にチェックを入れて Qt Creator を再起動してください。

# ModelEditor を使ってみよう

ModelEditor はプロジェクト形式ではなく、いきなり図を書き始めることができます。が、今回は Qt のサンプルのモデル図を書いていきたいと思うので、プロジェクトを先に開きます。

1.ファイル > ファイル/プロジェクトを新規作成を選び、開いたダイアログの左側の一覧から「モデリング」を選択し、「モデル」もしくは「Scratch Model」を選択してください。

![new_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/2e80a75e-b341-3165-38a5-a18d5bb4d38b.png)

* モデルを選択

ファイル名と保存先を指定します。任意のモデル名を入力してください。

![add_model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/1b247e11-6774-66ce-2121-290975228233.png)


![new_model_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/489d70df-fee3-36d6-8fde-92c11d8e494e.png)


* Scratch Model を選択

テンポラリのファイルが開きます。Qt Creator 左下の開いてるドキュメントにテンポラリのファイルが追加されます。この時、ファイル名は「model-XXXXX.qmodel」となっていますが保存されていません。ファイルを保存するには、テンポラリのファイルを選択して、右クリックするとコンテキストメニューが表示されるので、「model-XXXX.qmodelに名前を付けて保存」を選び、ファイル名、保存先を入力してください。

![add_scratch_model.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/ee1d236a-9e18-1aff-ba23-48d6dc391fe6.png)

![new_scratch_model_view.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/689d745c-0e53-5e55-37a9-7a458de459cd.png)


# 基本的な使い方

* 使い方は簡単です。追加したい要素がプロジェクトにあるのであれば、ファイルをエディタ部分にドラッグするだけです。もしくは、プロジェクトエクスプローラの右側に用意されているパレットから任意の要素をドラッグし、名前をつけるだけです。

* 関係線を引く場合は、始点となる要素を選択すると右上に操作の候補が表示されます。その中から目的の線を選び関係を引く要素までドラッグしてください。

**この時、要素間の位置によっては線が繋がらない時があるので、要素の位置を変えて試すと成功するようです。。。**

* 右下にプロパティが表示されるので、選択した要素のプロパティを編集することができます

# クラス図を書いてみよう

Qt に付属する計算機のサンプルを使ってみました。サンプルで用意された calclator や button をエディタ部分にドラッグしてみます。

![class_diagram_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/c5673645-2018-4594-3fa0-f5cc651c6f3d.png)


**他のプロジェクトのファイルはコンポーネント要素になってしまうようです。上図にある Qt フレームワークのクラスを追加するには手動で追加するしかありませんでした。**

![class_diagram_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/6f43c1d1-d4cd-04f4-b2ea-d22dcb37a68f.png)

**関係線は位置をずらしたり任意の位置で折り曲げたりできないので、2つのクラス間の関係線は重なってしまい非常に見えにくいです。右側のエレメントツリーから特定はできるのでが、ちょっと使いにくいです。**

# ユースケース図を書いてみよう

パレットの「UseCases」を選択するとユースケース図で必要な要素が表示されます。

![usecase_diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/61d1bd32-4b6f-734d-42dc-5e754cad3372.png)

**ユースケース図自体、複雑なことを図ではないので、使えるかなぁ。**

# シーケンス図を書いてみよう

パレットの「Sequences」を選択するとシーケンス図で必要な要素が表示されます。

最初、ライフライン（縦方向の線）が書けないのかと思いました。一般的なツールだとインスタンスを配置した時にライフラインも同時に表示されているのですが、何もありません。ライフラインを引くには「EndLineline」もしくは「Destruction」をインスタンスの下の方に配置して、インスタンスとの間に線を引きます。

![sequence_diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251604/9501fe64-11f0-b47e-ace7-69a9a2499df0.png)

**シーケンス図を使うにはちょっと厳しそうです。自分自身に対するメッセージが表現できません。実行指定もライフランの位置に配置されるわけではないので、自分で位置極めなどしなければなりません。インスタンスの位置をずらす時とても大変そうです。**

# おわりに

Qt Creator にデフォルトで付属しているプラグインなのだけど、クラス図の関係線の扱いを考えるとさらっと図を書くだけだとしても、ちょっと使いにくいなと感じました。

明日（既に今日...）は、@hermit4 さんが CMake 関係で何かを書くそうなので楽しみですね。

[^1]: [Astah*](http://astah.change, vision.com/ja/index.htmlhttp://astah.change-vision.com/ja/index.html) や [Enterprise Architect](https://www.sparxsystems.jp) が有名ですね

[^2]: 「っぽい」というのがミソです
[^3]: [ドキュメント](https://doc.qt.io/qtcreator/creator-modeling.html)には Universal Modeling Language と記載されていますね...
[^4]: [「Qt Creator 4.2 のSCXML Editorを使ってみる！」](https://qiita.com/Donokono/items/790b067307da8177add4) で紹介されています
[^5]: W3C で仕様策定されている SCXML
[^6]: Windows/Linux の場合は、上部メニューから ヘルプ > プラグインについて(P)... を選択してください