Qt 勉強会 @ Tokyo #61 参加報告 | QMLでタブページを実装

前回に引き続き今回も参加したので参加報告を記す。

概要

イベント情報
項目 内容
イベント名 Qt 勉強会 @ Tokyo #61
URL https://qt-users.connpass.com/event/92747/
ハッシュタグ #qtjp
主催者 日本Qtユーザー会
開催地 東京都新宿区新宿1-23-1 新宿マルネビル9F
開催日時 2018-07-14 Sat 13:00-18:00
参加人数 13
SNS https://social.senooken.jp/conversation/33635

connpassのページに登録していない人が1名いた。また,2人途中退出した。

作業

前回までの作業でQtの開発環境を検討できたので,元々作業していた内容にとりかかることにした。

具体的には,今後自分が開発していくアプリケーションで利用する機能の勉強だ。手始めに,タブページの実装にとりかかった。タブページはWebブラウザーやテキストエディターなどモダンなアプリケーションではほぼ採用されている。今後自分が作成する全アプリケーションで基本的に採用予定のGUIコンポーネントだ。

実装にあたって,特に技術的に問題となるのは,タブの動的な生成・削除,タブのドラッグだ。これらの機能をQtでどのように実装すればよいかがポイントとなる。

Qtでの開発はQt Widgets,Qt Quick Controls 1,Qt Quick Controls 2の3種類のモジュールが使える。この内,Qt Quick Controls 1はQt 5.11から廃止予定になったため,Qt WidgetsかQt Quick Controls 2の2択となる。QMLで作ったほうがシンプルになるので,手始めにQt Quick Controls 2での実装に挑戦した。

まず,ぶつかった問題がQMLでの開発にVS Codeは向いていないことだ。前回まででQtの開発にVS Codeを使うことにしたのだが,VS CodeではQMLはコード補完には対応できなかった。そのため,しかたなくQtCreatorで開発することにした。

タブページを実装するのに適したTabBar QML型があるのでこれをベースに実装を試みた。一番ネックになると思っていたのが,タブページの動的な生成と削除だ。思っていたより,インターネット上に情報がなく苦労した。

勉強会の当日は,「Dynamic QML Object Creation from JavaScript」のページを参考に実装を挑戦していた。その日は拡張モニターの持参を忘れたり,VS Codeで開発を進めていたため,作業効率が悪くて時間切れになった。

タブページの実装は自分にとって今後ずっとついてまわる重要な機能なので,帰宅後も継続して作業を進めた。勉強会の当日は,上記のページを参照してやるしかないと思っていた。上記のやり方が一番汎用性が高いのだが,複雑になるのでなにかいい方法がないか探していた。「Adding TabButton dynamically to TabBar | Qt Forum」によいサンプルが見つかった。

Qt Quick Contorls 2のTabBarはContainer型を継承しており,Container型のメソッドにaddItem(), insertItem(), removeItem() メソッドが存在するので,これを使えばスマートに実装できた。

その他に,タブボタン上に×ボタンを表示させたり,タブをドラッグで移動させたり,挑戦していた。タブを移動・削除した場合に,クリックの座標位置がおかしくなったり,狙った通りにいかなくて思っていた以上に時間がかかった。結局,納得のいくところまで作りこむのに1か月かかった。

成果

約1か月かけてできたのが以下のタブページだ。Qt 5.10.0でビルドして動作を確認した。

タブページのデモ

ソースコード一式は「QtExample/TabPageQML at master · senooken/QtExample」に格納している。

このタブページのサンプルでは以下の機能を実装した。

  • [+]ボタンを押下してタブページを追加
  • タブボタンをドラッグで移動
  • マウスホバーで[×]ボタンを表示
  • [×]ボタンの押下でタブページを削除
  • タブボタンをダブルクリックでタブページ名を編集

この他の課題に「タブページを画面外にドラッグドロップで新しい画面の作成」もある。これはやや難易度が高いのと,ひとまず自分の試作アプリには持ち込むつもりはないので保留とした。

いくつかバグがあり,無駄な処理がけっこう入っていてあまり気にいらない。

  • タブページ移動・削除時の座標を正しくするために,タブページの移動・削除時に毎回座標の更新 (該当箇所)
  • 座標の更新をするときにときどき,配置がおかしくなるので20 ms待機して画面幅を伸縮して配置を更新 (該当箇所)

さらに,最新のQt 5.11ではタブボタンをダブルクリックしてタイトルを編集しようとすると,文字が被るという不具合もわかっている。

Qt Quick Controls 2での実装で残念だったのが,タブの閉じるボタンを自分で実装しないといけないところだ。タブページの機能はアプリケーションに必須なのでこれくらいの機能はあってほしかった。

ただし,「タブウィジェットの作り方(QTabWidget) | QT && C++」を見る限り,Qt Widgetsでは最初からタブページの閉じるボタンの機能が実装されているようだ。

Qt WidgetsとQt Quick Controls 2のどちらがいいのかというのはまだわかっていない。そもそも,Qt Quick Controls 2はまだまだ開発途中なので安定していないのかもしれない。

結論

Qt Quick Controls 2で,GUIアプリケーションに必須のGUI部品であるタブページの実装に取り組んだ。

静的でシンプルな作りの部分は,簡単にスマートに作れた。しかし,閉じるボタンやタブページの動的な生成・削除など少し複雑な実装をすると,意図しない挙動をしてしまい,対処に泥臭い対応が必要となった。

Qt Quick Controls 2はスマートフォンでの動作も念頭に置いており,デスクトップアプリケーションのように複雑なことをするのに向いていないのかもしれない。また,Qt Quick Controls 2でのタブページの実装の情報自体がほとんどなくて手探り状態だったので苦労した。Qt Quick Controls 2は新しいモジュールで全体的にあまり情報がない。

今度はQt Widgetsで同じものを作って作りやすさなどを比較してみる。Qt Widgetsは昔から存在するモジュールなので,情報も多くて意外と簡単にできるのかもしれない。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です