先日公開しました、Susanooベータ版のメイキング的なのを書いていこうと思います。
意外と無かった問題
まず、家・会社の仕事を問わず、プロジェクト毎に必要となるスクリプトなどが毎回異なり、色々なスクリプトをマイドキュメントにバンバン入れていくと、グチャグチャになるし、競合して不具合起こすかも。。。かと言って、バッチファイルを作るのも面倒!!(´;ω;`)ウッ…
あと、自分でツールを作っている時に、クリーンな環境、ツール用の環境を簡単に用意したいというのが物語の始まりでした。
「アプリケーションランチャーなんて、世の中に沢山あるし、フリーでいいかな」っと思ったのですが、環境変数、コマンドライン引数をそれぞれに割り当てようと思うと、途端にありません(;´∀`)
無いなら、作ってしまおう!そんなノリで、制作を始めました。
開発環境
アプリケーションを作るには色々な方法がありますね。迷う。。。
Mayaのツールを作っている人ならお馴染みのPySideでGUIを作って、ガシガシ書けるPythonかなーっと思ったのですが、作りたいのはスタンドアローンアプリケーション。配布がちょっと面倒。それなら、Visual StudioとQtで作って、EXEで配布できるようにしようかなーっという感じで選び以下のようになりました。
Visual Studio 2013 Community
Qt 5.7
Qt add-in
途中、諸事情であまり家のPCが使えなくなり開発が停滞してしまい、ノートPCなら使える!けどOSX!XCode使ったこと無いよー、、、となりました、、、(゚A゚;)ゴクリ
ふと、Qt Creatorってどう??っと思い、使ってみたらドンピシャでした。WindowsとOSXでほぼ同じ状態で開発できるのは素晴らしい!コードを書く、ビルドする!くらいならヘルプを見なくてもわかる感じです(*´∀`*)b
最終的に開発環境は、こんな感じです。
Qt Creator
Qt 5.7
Qtを使ってアプリケーション作るなら、Qt Creatorでいいかもっと思い始めました。
アプリケーションランチャの一覧
アプリケーションランチャの一覧では、QListViewを使用しています。いつもなら、QStandardItemModelと、QStandardItemだったのですが、ちょっと小洒落た?見た目にしたいと思い、QStyledItemDelegate、QAbstractListModelの合わせ技となりました。
この辺りは、QListViewをカスタマイズ表示する!的な記事が参考になるかと思います。ちょうどCG系でいくと、DF TALKにあるTD小野さんの記事がわかりやすいと思います!
PySideでリストをカスタマイズするぞ! ~応用編「delegate」~
View、Delegate、Modelが自由にカスタマイズできるようになると、View系の表示が楽しくなると思います!(`・ω・´)ゞ
アプリケーション情報の編集
基本的な部分はすぐに出来上がったのですが、コマンドライン引数、環境変数の編集部分でめっちゃ悩みました。どんな感じになるかな?っと適当にWidgetを並べて作ったら、ヒドイことになりそうだったので、QTableViewを使用しました。アプリケーションランチャの一覧と同様に、QStyledItemDelegate、QAbstractTableModelとの合わせ技です。
変数名の部分は、QStyledItemDelegate::createEditorで、QComboBoxを作って、定義にある内容をQCompleterを突っ込んで、終了です。
ちょっとトリッキーなのが、QStyledItemDelegate::createEditorで作るエディタを、外部ファイルの定義依存にしました。Column0に設定した文字列に応じて、定義と照らしあわせて、Column1のエディタを変更するといった感じです。これで、環境変数名に応じて、適切な値が設定しやすいようにしました。
ただ1つだけ、セルの中に収まりそうなエディタを作ったので、QStyledItemDelegate::editorEventで処理を挟み込みました。ちょっとこれでいいのか自信ない、、、けど他のアプローチが思いつかない感じです(;´∀`)
Drag&Drop
またまたややこしい系のヤツです。アプリケーションランチャーのD&Dは、QAbstractListModel側で処理を書きました。
QAbstractListModel::supportedDragActions、QAbstractListModel::supportedDropActionsで、D&Dできるアクション(コピーとか移動)の応答、D&Dでお馴染みの、mimeTypesの設定、リスト内で移動できるように、QAbstractListModel::dropMimeDataの処理と言った感じです。
ちょっとややこしいデータをmimeTypesに突っ込むなら、QDataStream &operator<<と、QDataStream &operator>>を記述してあげるとコードがスッキリするかもしれません。
この時、Q_DECLARE_METATYPEの設定をし、main()の中でqRegisterMetaTypeStreamOperatorsの設定をしないとドツボにハマるかもしれません。
Qt5からはJSON使える
僕の脳みそがQtが4.8で止まったままなので、保存するファイルは全部QSettingsでiniだーっと思ったのですが、たまたまQt5からJSONが使えるとしって、アプリケーション情報の保存はJSON!全部JSONにしたかったけど、ちょっと気付くのが遅かった、、、いずれ、、、きっと、、、w
で、JSONというと、Pythonだとすご~~~~~く読み込み・書き込みが簡単で鼻血がでそうだったのですが、QtのJsonはそうは問屋がおろしませんでした。
Pythonだったら、「name =json[“name”]」って感じで取得できると思いますが、Qtでは、「json[“name”].toString()」と言った感じになります。「to~~()」系がちょっと億劫。配列や連想配列が入ってくると、目的の所にたどり着くまで「to~~()」だらけになります。
なので、内部で管理しているデータClassに、toJson()、fromJson()を用意してコードがあまりグチャグチャにならないようにしました。
StyleSheet
QWidget::setStyleSheetなどを使って、Widget個々にStyleSheetを記述すると、個人的にはメンテしにくいし、読みにくいし、複数のスタイルに対応できない!っということであまりしません。
Susanooでは、style1.qssというファイルを作り、qApp->setStyleSheet()を使って一括登録しています。ちょうど、HTMLをCSSファイルで装飾する感じですね。こうしておけば、読み込むファイルを切り替えるだけで、UIのスタイルをコロコロ変えられて便利かと思います。
ごく一部のUIを変更したい場合は、以下のようにしてみるといい感じになると思います!
- setObjectNameでつけた名前を使って、QCheckBox::indicator:checked#FavoriteCheckBox
- setPropertyを使って値を設定して、QLineEdit[state=”Acceptable”]
- 両方合わせて、QLineEdit#PathLineEdit[state=”Acceptable”]
今後
最後まで読んでくれてありがとうございます。引き続き、頂いたリクエストなどを反映していこうと思います。
何かございましたら、当ページのコンタクト、Twitter、コメントなどからお願い致します!