こんにちは。田原です。
Qtは非常に巨大なライブラリなので様々な機能を持っていますが、Qtを使いたい最大の動機はやはりGUI開発と思います。Qtは、そのGUI開発用に2つの全く異なるフレームワークを提供しています。Qt WidgetsとQt Quickです。今回はこの2つのフレームワークの特徴について解説し、当講座で主に取り扱うフレームワークの結論を説明致します。
1.Qt WidgetsとQt Quickの歴史
Qt Quickは比較的新しい技術で、2010年にリリースされたQt 4.7にて初登場しました。約10年前というと大昔のような気がしますがC++11が規定される1年ほど前なので実はつい最近の出来事のようにも感じます。(単に私が歳をとっただけかも知れません。)
Wikipediaによると最初のQtは1995年にプレリリースされているようです。Qtは当初からGUI開発できました。ここによると当初よりWidgetsベースでGUI開発できたようです。
2.使い勝手の比較
使ってみた感じですが、C++プログラマーにとっては Qt Widgetsの方がQt Quickより格段に使いやすいです。
2-1. Qt Widgetsの場合
Qt Widgetsは、C++とのインタフェースもC++ベースですので面倒な手順が不要です。
更に、Qt用の標準のIDEであるQtCreatorはQt Widgets用のフォーム・デザイナを内蔵しています。これはWYSIWYGなデザインツールです。必要な機能を全て網羅しており使い勝手も良く十分に使えます。
逆に、Qt Widgetsのデザインを記述するファイルは .ui という拡張子を持つテキスト・ファイルですが、その内容はXMLなので手で書くのはたいへんです。ですので、フォーム・デザイナーを使っている人が多いだろうと思います。
2-2. Qt Quickの場合
これに対して、Qt QuickはQMLというGUIを記述するための専用の言語を使います。(QMLはQt Modeling Language、もしくは、Qt Meta-Object Languageの頭文字のようです。)
GUI記述言語としては非常に強力なのですが、C++とは大きくかけ離れた概念の言語です。HTMLと同様にJavaScriptを使って「ロジック」を記述できます。そのJavaScriptとC++をインタフェースすることになりますが、その手間がQt Widgetsより(2手間ほど?)余分にかかります。
また、QtCreatorはQMLを出力するデザイン・ツールを内蔵していますが、QMLがロジックまで記述できるせいなのか機能が圧倒的に不足しているため、あまり使えません。ただし、Jsonライクの構文なので、慣れ親しんだC++と「見た目」はちょっと似ていますし、XMLに比べると可読性・メンテナンス性はかなり良いと感じます。例えば、要素の記述は 要素名{ 内容 } です。(これに対して、XMLでは <要素名>内容</要素名> ですね。)
ですので、QMLは手で記述する人が多いと思います。
2-3. Qt WidgetsはC++プログラムでもGUIを直接書けるけど...
Qt Widgetsは、C++プログラムで直接GUIを生成することもできますし、検索するとそのようなサンプルも多数でてきます。例えば、「ラベルを作ってテキストを設定しウインドウとボタンを作り、ウィンドウにボタンを貼り付けて表示する」ようなプログラムをC++で書くことができます。
しかし、これは超手間がかかります。個人的には現実的ではないGUI開発手法と思います。
3.将来性の比較
どうもQtの開発スタンスはQt Quickへシフトしているようです。公式ページのリリース・ノートに過去のQt 5のリリース情報も一覧されています。このNew Featuresを見るとQt QMLやQt Quickは毎回新しい機能が追加されていますが、Qt Widgetsの方はあまり追加されていないようです。既に「枯れている」状況なので新機能を追加する必要性が乏しいとは思いますが、勢いはQt Quickの方があります。
4.WebEngineViewとWebViewについて
ちょっと話がそれますが、現代のGUI開発フレームワークとして最も進歩しているものは、WEBブラウザで表示するHTMLベースのGUI開発と思います。時が経つにつれてより強力な表現力をより容易に実現できるように進化しています。使われる場面も非常に多いためエンジニアの人数も多く、複数のWEBブラウザの状況を見ると開発にも多くの資本が投入されていると思います。
HTMLとCSSとJavaScriptでGUIを記述し、C++アプリのGUIとして機能させることができると、リーズナブルなコストで高度なGUIを開発できるのではないかと思います。
4-1. .NETのWebBrowserコントロールはHTMLページをアプリで表示/修正できる
Microsoftの.NETではWebBrowserコントロールを使うことができます。
これは、HTMLページを表示するだけでなく、プログラム側からその各要素を取得したり、修正したりすることができる強力なものです。
しかし、使用しているWebブラウザ・エンジンは開発終了して久しいInternet Explorerです。また.NET上の技術ですのでネイティブなC++から直接扱うことはできません。(.NET上のC++/CLIはMicrosoftが独自に拡張した特殊なC++です。)
4-2. QtのWebEngineViewとWebViewはHTMLページをアプリで表示できる
このように、一般的にはC++アプリのGUIとしてWEBブラウザベースのGUIを使うことは難しかったのですが、Qtはこの機能について強力なサポートがあります。それがWebViewとWebEngineViewです。
これらはC++アプリの内部にHTMLベースのGUI表示機能を内蔵させ、C++と通信できるようにしたQtのGUIコントロールです。
WebEngineView
WebEngineViewは、Qtに内蔵されたChromiumベースのWEBブラウザ・エンジンを使ってHTMLページを表示するコントロールです。
Qt WidgetsとQt Quickの両方で使えます。残念ながらiOSの制約によりiOS上では動作しません。(全てのアプリはOS以外のWEBブラウザ・エンジンを使ってはいけない)
Windows版のQtのWebEngineViewはMSVC版でのみ使えます。(当講座の第1回目でインストール方法を解説しています。)
Windows版のQtはMinGWというC++コンパイラにも対応していますが、Qt公式サイトからインストールできるQtのMinGW版はWebEngine非対応です。QtのWebEngineをMinGWでコンパイルする難易度はかなり高いようで成功したという報告を見たことは有りません。できないわけではないのかも知れませんが、廉価版とは言えCore-i9と32GBytesメモリ高速なSSDを搭載したコンピュータでもビルド1回に数時間かかりますので、追求するのは厳しそうです。
WebView
WebViewは、OSが持つWEBブラウザ・エンジンを使ってHTMLページを表示するコントロールです。
WebViewは、Qt Quickでのみ使えます。そして理由は複雑なのですがPC(WindowsとMac)では使えない場合があります。しかし、Qt Quick上のWebEngineViewはWebViewの上位互換性が概ねあるようですので、Qt Quick用のWebEngineViewに置き換えれば使えます。
理由は複雑
HTMLページとC++間で通信しないとあまり意味がありません。その方法としては、QWebSocketを使う方法と、Chromium IPCという技術を使う方法2つが提供されています。
前者(QWebSocket)は要するにWebSocketを使う方法ですので汎用的ですが、httpコマンドを受け付けるTCP/IPポートをローカルPCで開きます。PC外部との通信にも使えるためセキュリティ上のリスクを多少なりと上げますので使えない/使いにくい場合があります。
後者(Chromium IPC)は、Chromiumがサポートするパイプを使ったプロセス間通信です。PC外部との通信には使えないのでセキュリティ・リスクは低いです。
WebEngineViewはChromium IPCをサポートしていますが、WebViewはサポートしていないのでWebSocketを使わないとHTMLページとC++の通信が行えないのです。
QtのドキュメントにChromium IPCの使い方の解説はあまりありません。Qt WebEngineView QML TypeのwebChannelプロパティで使います。
またQt Widgetsですがサンプルがあります。markdowneditorです。
まとめると
まとめると、現代最強と思われるHTMLベースのGUIを使ってC++アプリを開発するなら、Qt QuickでWebEngineViewもしくはWebViewを使うのがベストと思います。
うんちく
QtのWEBブラウザ・エンジンのサポートは一度大きく変わっています。Qt 5.5前後頃までは、WebKitと言うWEBブラウザ・エンジンを内蔵していました。しかし、その後ChromiumベースのWEBブラウザ・エンジンに置き換わりました。Chromium は Google Chrome にも使われています。また最近Microsoft EdgeもChromiumベースになりました。このような歴史的経緯のせいでWebViewという用語が混乱しています。QWebViewとQt WebViewは見た目がそっくりですが、全く異なるものです。QWebViewはWebKitを用いたQt Widgets上のコントロールのクラス名です。Qt 5.6で廃止されています。
Qt WebViewは上述のWebViewでQt 5.5で登場しています。更にWebEngineViewはQt 5.4で登場しています。検索した時にQWebViewにもヒットすることがあるのでご注意下さい。
5.HTMLを置き換え得るQMLという選択
「現代最強と思われるHTMLベースのGUI」と申しました。これはどちらかというと表現力が高いことを指しています。高度なGUIを記述できるという意味です。ですが、必ずしも生産性が最適化されているわけではないと思います。
HTMLはタグで記述するため可読性とメンテナンス性が酷いです。
またHTMLは原始的なドキュメント記述言語なので、MS Wordを使う場合と同じく、同じことを複数回表示したい時は、いちいち複数回記述するしかありません。HTML自体には「部品」や「雛形」を記述するような機能がないからです。これはプログラミング言語としてみると、DRY原則を頭からガン無視しているので、プログラマーとしてはストレスフルです。
QMLはその辺りについて革命的な機能を導入しています。
HTMLのタグ(pとかdivとかaなどなど)は、QMLの型(Rectangle、CheckBoxなどなど)に相当します。
HTMLのタグをHTMLで新たに拡張すことはできませんが、QMLの型は他の定義済の型を拡張して新たに定義することができます。
更にQMLは雛形(template)も定義できるようです。
HTMLの属性(タグ名の次に記述する class=”xxx”やstyle=”yyy”などなど)に相当するものとしてQMLにも属性があります。
HTMLはタグの種類ごとに指定可能な属性は決まっていますが、QMLの型の属性は型を定義する時に新たに定義できます。
これにより、プログラマーはGUI部品をQML型として他のQML記述の中で自由に使うことができます。
C++の型とQMLの型
この2つは似ているところとかけ離れているところが混在しています。C++と同様QMLも一種のオブジェクト指向言語です。
そして、オブジェクト指向言語にはC++やJavaに代表される静的なクラスと動的に生成されるインスタンスが明確に区別されている「クラスベース」のものと、Smalltalkのようにクラスとオブジェクトが区別されてなく新たなオブジェクトを生成する時はオブジェクトを複製して作り、オブジェクトの構造を動的に変更できる「プロトタイプベース」の2つの流れがあります。QMLはどちらかというと「プロトタイプベース」のオブジェクト指向言語です。
ですので、ガチガチのクラスベースのオブジェクト指向言語であるC++に慣れたプログラマーがQMLを使うためには頭を切り替える必要があります。しかし、QMLはC++の右辺値参照ほど難しい概念ではないですし、慣れればなんてことない筈です。
GUI部品の拡張
QtQuickはまだ若いこともあり、既に用意されているQMLのGUI部品では不足するようなケースもあるかもしれません。そのような場合、C++側でGUI部品を新たに定義することもできるようです。
ここまでやるのはできるだけ避けたいですが、必要な時はGUI部品を1から作れるので安心感はあります。
6.考察と結論
正直なところ、将来については分かりませんが少なくとも現時点では、Qt Widgetsを使った方が生産性は上がります。Qt Widgetsの方が古くこなれていますし、C++との親和性も高いです。Qt Quickは新しいのでQt Widgetsに比べると機能も不足していますし、発展途上という感じです。C++とのインタフェースも面倒です。
しかし、同様に将来については分かりませんが少なくとも現時点では、HTMLベースのGUI開発を導入し、かつ、iOSもターゲットとする場合はQt Quickを使う以外の選択肢はありません。
更に、マクロやインクルードの概念のないHTMLに辟易としているプログラマーにとってはQMLは救世主になるかも知れません。確かにまだ若くこなれていませんが、C++プログラムを書くのと同程度の苦労でGUI部品を新たに定義できるという機能には可能性を感じます。
そこで、当講座では将来性を期待してQt Quickを使って解説を進めたいと思います。
7.あとがぎ
今回は、裏で色々調べていたら膨大に時間を消費してしまい、本当はQt Quickのサンプルを提示したかったのですが、時間切れになってしまい、文字ばかりで申し訳なかったです。
Qt Quickの入門記事は結構多いのですが、Qt Quick自体がどんどん進化しているため、古い情報と新しい情報が混在していて何が良いのか本当に混乱してしまいます。そこで、次回は、最新版のQt Quickで開発の「雛形」的なサンプルを定義できるよう頑張ってみます。
それでは今回はこの辺で終わります。お疲れさまでした。
大変勉強になりました。
仕事でQtのライブラリを使用したプログラムの修正を行ったのをきっかけに、
Qtについて少し独習していたところ、本サイトにたどり着きました。
Qt全般の情報についても、古い情報と新しい情報が混在しているため、
初学者にとって少し難しいと感じていました。
最初に買った書籍もQt Quickのもので、知りたいこととちょって違って困惑しました。
その後、Createrを使ったQtの書籍も購入しましたが、現時点では、日本語だとすべてQt4のものなので、
いくらか読み替えてプログラミングする必要がありました。
その点、本サイトは情報が新しく、非常に参考になりました。
これからも良質な情報の発信をよろしくお願いいたします。
丁寧なコメントありがとうございます。
Qtは今も成長を続けているので、本当に情報の取捨選択に困ることがありますよね。
でも、慣れると本当に便利なフレームワークなので頑張って下さい。
私も微力ながらお手伝いできれば幸いです。
Pingback: Qt あれこれ | 秋葉ちゃんねる【別館】