不愉快なQtの旅


今日はQtで小さなプログラムを書いて、ネットから何かを捕まえて、ローカルに保存することを解析してみました.簡単な機能ですが、とても書き心地が悪いです.
Qtが提供するライブラリをざっと見てみると、何でも揃っているようです.多くのGUI Widgetは豊富なインタフェースを構築することができ、便利なQHttpはWebページをダウンロードし、QRegExpを使用して解析することができ、Qtの強力なQTextCodecは各種の符号化の間で変換することができる.Qt 4はMCV方式を提供しており、トランザクションとビューを簡単に分離することができます.すべてはそんなに完璧で、私のために準備したようです.しかし、それらは私のために用意されたものではありません.
QHttpを使ってファイルをダウンロードするのはとても簡単だと信じています.そこで、まずインタフェースをすることにしました.各項目がModelのダウンロードセッションに対応し、QLabelやQtrogressBarなどのWidgetを使ってセッションの詳細を組み立てる展示をする予定ですが、できればCompact ViewとExpanded Viewの2つのモードで、現在選択されている項目だけにExpanded Viewを使用したいと思います.Esperanzaのプレイリストのように見えます.
Qtの例やQListView、QTable ViewなどのAPIなどのドキュメントを見て、QtのMCVモードを大体理解しました.
  • Modelはデータを持っています.
  • Viewはデータの表示を担当します.コントローラの役割も担当しています.
  • には、単項データの編集(通常はリストやTableのデータがある)を実現するために使用できるDelegateというものもあり、細かく表示する場合はViewの表示機能に取って代わるDelegateもあります.

  • 今、私はQAbstractItemModelから自分のModelを継承して自分のダウンロードセッションを保存し、管理し、QAbstractItemDelegateを継承してセッションを表示するだけで、ViewはデフォルトのQTableViewなどを使用することができるはずです.
    ここまで万事順調だ.Modelの働き方を詳しく調べてみました.
  • Modelは、ビューがデータの行数と列数を知ることができる関数を提供します.
  • ViewはModelのindex関数を呼び出し、ある行のある列の要素のインデックスを取得します.これはQModelIndexです.
  • ViewはModelのdata関数を呼び出し、以前に取得したインデックスを渡して特定の要素の値を取得します.
  • Modelは、dataChangedのような信号を使用して、Viewデータが変更されたことを通知する.

  • そこで、Modelでセッションのリストを維持し、各セッションはModelの状態が変化したことを信号で通知し、ModelはViewにビューの更新を通知することにした.しかし、詳細は面倒で、たくさんのセッションがModelに接続され、信号が送られてきて、どのセッションなのか区別できず、各セッションにidを付けて、Modelがidを管理し、信号を送信するときにidを持っていくことができます.しかし、今はViewがModelにデータを要求しに来ています.それは行と列のインデックスを標識として使っています.一つはidを行番号にすることです.そこで、あるidのセッションがステータスが変わったと信号を送信しました.私はちょうどそのidについてViewの何行目のデータが変わったかを伝えることができます.しかし、ダウンロードが完了したセッションを削除したい場合は困ります.削除した後、残りのセッションの行番号が変わりますが、idは自動的に同期されていません.毎回、あるidのセッションレポートステータスが変更されるたびに、Modelはすべてのローを検索し、どのローがidに対応しているかを見て、Viewにローが変更されたことを通知する必要があります.これは、Viewがデータのインデックスとして行列を強制的に使用したため、非常に面倒に見えます.でも大丈夫です.いっそすべての行が変わったことを直接報告すればいいです.
    Delegateもかなり複雑で、編集を実現するにはWidgetを提供し、表示するときはpaint関数を実現します.自分で描くのではなく、一連のWidgetを使って組み立ててViewの表示を実現したいと思っています.メールリストを検索すると、Qtは今確かにこのような便利さを提供していないことに気づきました.自分で描くしかありません.幸いなことに、Qtは基本的なWidgetを描くことができる関数を提供していますが、Layoutのような機能は自分で管理するしかありません.もう一つおかしいところがあります.実際のプログラムのソースコードをダウンロードしてブラウズした後、ViewがModelからデータを取得したときにRoleパラメータがあり、Roleが異なるときは異なるものを返すことを望んでいます.フォント、色、背景、アイコンなどがあります.もともとViewで処理すべきものはすべてModelから取らなければならない!最近ではRuby on RailsでWebアプリケーションを書くことが多く、MCVモードは使いやすいと思っていますが、今ではQtのこのフレームワークでは異常に違和感を感じています.
    苦痛な符号化を経て,最後に理想的なUIインタフェースを実現した.今から見れば、やはりHTML+CSSがインタフェースを書くのが気持ちがいいですね.HTMLは何年も苦労していますが、インタフェースを作るための言語です.近いうちにデスクトップアプリという専用UI言語も通用するのではないかと思いますが(その時デスクトップアプリがあったら)、Mozillaやマイクロソフトにも似たようなものがあるようですね(XULやXAMLとか)?
    次はダウンロードですが、QHttpは使いやすいので、ダウンロードしてQTextCodecでエンコード変換し、QRegExpで解析します.ドキュメントを見ると、QRegExpでは複数行の検索がサポートされていないことがわかりました.その後、ダウンロードしたファイルがずっと間違っていることに気づきました.長い間フォローしていたら、QHttpはダウンロードするパスを指定するのが面倒だったのに、QUrlを使ったのはかえって手伝っているようで、結局リソースの位置が間違っていました.
    Qtの体験とこのプログラムを一時的に一段落させることにしました.今日の経験は本当に私の心の中で地位の高いQtライブラリを一気に下げました.Qtで構築されたKDEは、どこでもデザインが親切だと思っていますが、今日Qtを使うと、多くの場所にあるべき機能がないような気がします.あるべきではない機能がたくさんあって、特に違和感があります.転職というのは一番いい休みです.まずこの小さなプログラムを置いてください.そうしないと、Qtに偏見を蓄積しすぎます.