目次:
私は今まで、WindowsとJava中心にプログラムを作成していましたので、Linuxでのプログラミングは全くの素人です。
目標は、FreeNoteのQt版を作成することとします。
…失敗〜 (T-T)
なぜか、ビルドがうまくいかない。
マニュアルを見ろ小僧!ということで、CSIDE for Linux Zaurus Developerのインストール方法を良く読む事にした…。
えーと、なになに…。
…! UNiXにしてたじゃん…。_| ̄|●
仕方ないので、全環境をアンインストールして再挑戦。
さて、再インストールが終わった後に、サンプルプログラムを作成して、ビルドすると…。
すげぇ、すげぇぞ! CSIDE!!
この時点で、かなり満足。もうちょいと評価して、問題なければ、是非とも購入にあたりたい。
こんなときは、先人に学べということで、とりあえず、CSIDEが自動生成するプログラムを参考にしてみることにします。
connect(quit, SIGNAL(clicked()), this, SLOT(goodBye()));
との記述を見つけました。
ちなみに、どのシグナルが用意されているかは、Qt DesignerでF3を押した後+カーソルで部品を選択すると参照することができます。
多分、シグナルが用意されているはず…。とWindow(Widget)のシグナルを探しても無い。
なんでかな?
ものは試しに、mouseMoved等のキーワードでヘッダファイルをgrepしてみると…WidgetのベースクラスであるQWidgetは、mouseMoved等のマウス系イベントを処理するメソッドを持っていることがわかりました。
あ、なるほど。
マウスイベントはインタフェースが既に用意されているので、上書きして使うってことか!
ということで、
ちなみに反応ですが、ネイティブだけあってすさまじく良いです。
てなわけで、Qt版FreeNoteには、かなり期待できそうです。
プログラムでは、こんな感じです。
これをpaintイベントでスクリーンに上書きします。
これで、FreeNoteの基礎となる部分は完成しました。
汚くて恥ずかしいのですが、一応、ソースを公開します。
QTのリファレンスを見てみると、QWidgetよりもQCanvasの方が高速に描画するとのことなので、
実際の実装は、QCanvasの方にするべきだと思うのだけど、QCanvasの使い方がいまいち分かってない。
とはいえ、実際は、書き込む領域の大きさをQVGA指定した場合は、C760でのパフォーマンスはVGAでも問題ないことまでは分かっており、遅い原因がQPixmapにあるのかQWidgetにあるのかはまだ分かっていません。
この一週間ほど、仕事が忙しすぎて、正直全くコーディングの時間がとれないこともあり、クラスの使い方なども深く調べられないところもあるけれども、
りなざうには、GPLによる優れたソースが多く公開されているので、そのへんを参考にしながら、少しずつでも進捗させたいと思っています。
とりあえずは、次の3連休でどれだけ時間が取れるかがミソですな。
QCanvasを親Widgetに追加するには、以下のようにします。
このままだと、QCanvasViewにスクロールバーが表示されないので、setVScrollBarModeとsetHScrollBarModeをAlwaysOnに設定します。
なんと、QCanvasViewが左上に小さく表示された状態のままでわないかっ! Σ(゜д゜) ハゥッ
そういえば、GUI部品って追加したあと、サイズを調整する必要があったわいな〜。
FreeNoteはツールバーとViewPortしかないので、レイアウトは、縦に並べるQVBoxLayoutにすることにしました。
メインウィンドウに追加したQCanvasView(cv)をレイアウトするコードは以下のようになります。
と、勇んで実行!!!
…あれ? うまく配置されない?(^^;
どうもレイアウトが効かない様子…(--;
原因究明のために、色んなソースコードを見て回っていると、あるサンプルソースに以下の記述が…
…
えー、レイアウトマネージャは、activateしないとならべてくれないんですか、そうですか。
紆余曲折あったものの、これで、どんなサイズでも調整できる画面なるものが出来上がりました。
FreeNoteは、PolyLineの集合体なので、(おそらく)QCanvasPolygonのサブクラスを実装することになると思いますが、
Java版で独自に描画情報を管理していた部分をQCanvasに委託できるのであれば、更に効率よくプログラミングできそうです。
うーん、ス・テ・キ♥ですね。
ただ、ちょっと気がかりなのは、
このまま、楽々プログラミングできるのか、それとも、Java版同様、ちょっと複雑な処理が必要となるのかは、
この辺の動作次第といったところでしょうか?
何はともあれ、使い方次第では、非常に面白くなることが予測されるQCanvasは、今後の開発でもいろいろと活躍してくれそうな雰囲気です。
(1).描画の途中の軌跡をどう管理するか?
要は、QCanvasItemのサブクラスで表現するほか無いようです。
実験君をしているうちに、QCanvasに追加されたQCanvasItemが、QVanvas外で解放された場合、QCanvasの管理からも外される(ように見える)事に気がつきました。
この性質を利用して、軌跡は以下の様に処理することにしました。
2.追加したQCanvasLineはQCanvas外で管理(QList
3.ペンが離れたら(mouseReleased)今まで追加したQCanvasLineをQCanavasPolygonのサブクラス(自作)に変換。
4.(3)のオブジェクトをQCanvasに追加。
5.管理している軌跡をクリア。
これにより、C760でも追従性が落ちることなく、描画可能となりました。
(2).QCanvasをリサイズした際のメモリコストは、どれくらいか?
確かに、6400*4800位は余裕で持てますが、12800*9600くらいになるとさすがにパフォーマンスが落ちてきます。
また、6400*4800でもVGAの100画面分…、必要十分な広さでは?とも思うのですが、C700のようにメモリ不足が懸念されるマシンでも、
快適に動かす為には、なるべくメモリの消費は抑えたいところです。
以上の事から、Qtのステキな機能を利用して楽々コーディングする野望は、ちょっとあきらめて、
スクロールに関しては自分で制御することに決めました。
ところが、QCanvasを利用したFreeNoteで描画を続けていくと、
描き進めるうちにだんだんとペンの反応が鈍くなる現象が見られるようになりました。(T-T)
結局、QCanvasを使うのは、使用感からして無理と判断し、QWidgetで再実装することにしました。
ところで以前、QWidgetでの描画は反応が無理っぽいという話をしましたが、実は、
実装がタコだったことが判明しました。
先日、Qtプログラミング入門を入手したのですが、これには、簡単なお絵かきアプリの例が出ています。
これは、ダブルバッファも含めていろいろ役に立つサンプルなのですが、この通りに実装したところ、なんと、
SL-C760でも全然反応が落ちない!。
わたしは、ダブルバッファに描画をし、repaintで表示させるというロジックを組んでいましたが、
このサンプルでは、ダブルバッファとQWidgetに両方描き込むことによって、なるべくrepaintをさせない。
というものでした。
repaintのコストは結構なものなので、なるべくrepaintしない方が反応がよいということですね。2003/07/12 はじめに
LINUXザウルスを入手して約一年、その間のプログラミングの中心はJavaでした。
一度プログラムを作ってしまえば、PCだろうが、MIザウルスだろうが、SLザウルスだろうが動いてしまうJavaは、非常に魅力的な言語でした。
しかしながら、ゲームなどを作っているうちは特に不満は無かったものの、
今年に入って初のアプリケーションソフト FreeNoteを作りはじめてからというもの、
Virtual Machineであるがゆえの応答の遅さや、サポートの遅さに歯がゆい思いをすることが多くなりました。
もう、自分の満足のいくアプリケーションを作るには、ネイティブの環境で作るしかない…と考え、初のLinuxプログラミングにチャレンジすることにしました。
良い機会ですので、プログラミング環境の構築を含めて、開発の経緯を日記形式で綴っていこうと思います。
#追々Tips等はまとめていくつもりです。
現在多忙のため、どれだけのパワーが割けるか、心配ではありますが、長い目で見守っていただければと思います。
[TOPへ]
2003/07/12 開発環境の選定
Qtアプリケーションを作るためにまずは、開発環境を選定することにします。
私は、とてもヘタレなので、できれば、Windows上のIDEで開発したいと思い、CSIDE for Linux Zaurus Developerを採用することにしました。
幸いにも、20日間フル機能を使える評価版が提供されており、前もって資料請求をしていたのです。
#資料請求によって、評価版が入手できます。
[TOPへ]
2003/07/12 開発環境の構築
CSIDEの評価版を入手したため、早速環境構築をすることにしました。
評価版のCDをドライブに入れると、インストールメニューが立ち上がるので、手順通りにインストール。
全部終わったところで、そのままサンプルを作って実行〜!。
CSIDE for Linux Zaurus上からコンパイルするためには、「Default Text File Type 」の設定を必ず「DOS」に設定してください。
#ちなみに、cygwinのアンインストールは、インストールディレクトリ毎削除し、レジストリでcygwinのキーを持っている場所を削りました。
おお、ちゃんとビルド出来るではないか。
さっそく、SL-A300にデバッグサービス(csideserver)をインストールしてデバッグ開始。
何の問題もなく、SL-A300でサンプルアプリケーションが実行された。
[TOPへ]
2003/07/12 イベントの実装
GUIアプリの実装には、イベントの仕組みの理解が必要です。
Javaでは、イベントのリスナーを部品に追加してやることでイベントを実装できますが、Qtではどうなのだろう?
もう夜だし、私はADSLも通わぬど田舎に住んでいますので、今からQtプログラミングの本など購入には行けません。(T-T)
すると、コンストラクタに、
ソースを見るとgoodBye()がイベントの中身でしたので、これが、イベントの指定だとわかりました。
どうやら、SIGNALでイベントを指定し、SLOTで処理を紐付けるようです。
あと、ヘッダーファイルを直接見ても良いです。signals:という宣言部があるので、そこがシグナルらしいです。2003/07/12 マウスイベントの実装
FreeNoteを作るには、何はなくともマウスイベントが必要です。
Javaでは、MouseAdapterやMouseMotionAdapter等を追加するのですが、Qtではどうするのでしょう?
void mousePressEvent(QMouseEvent *);
void mouseMoveEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
を追加してやると、めでたくマウスの動きを追えるようになりました。
2003/07/13 ダブルバッファ
ちらつき無く描画するためには、ダブルバッファの実装が必要です。
Javaでは、Imageオブジェクトに書き込みを行い、
paintイベント内でスクリーンにがばっと上書き(drawImage)するとちらつき無く表示できます。
Qtでは、QPixmapというクラスを使って描画バッファを作成し、
QPainterクラスを経由して描画を行います。
px,py:描画の開始ポイント
pix:QPixmapオブジェクト:QPixmap* pix = new QPixmap(画面サイズ);
プログラムでは、こんな感じです。
興味のある方はご覧下さい。(以外と簡単ですよ)
[TOPへ]
2003/07/17 C760のパフォーマンス問題
前回、FreeNoteの基礎部分のソースを公開したものの、速度を調べてみると、A300での速度は申し分ないが、C760での速度はいまいちな感じ。
(それでも、Javaに比べれば全然ましなんだけど…)
どうやら、描画に手間を取られて、取りこぼしが生じているっぽいです。
うまくすると、FreeNoteのコアなロジックを殆ど書かなくても良いような感じなのだけど…。
これがどちらの原因かは、今後(必要があれば)追求してみたいと思います。
[TOPへ]
2003/07/18 スクロールバーを使ってみる
レスポンスのチューニングはおいおいやるとして、とりあえずは、FreeNoteに必須の機能であるスクロールバーの実装を試してみることにしました。
Qtでスクロールバーを扱うには、QScrollBarを親Widgetに追加するか、QScrollView(もしくはそのサブクラス)を利用するからしいのですが、
先日からQCanvasの利用を検討中ということもあり、QScrollViewのサブクラスであるQCanvasViewを使うことにしました。
[TOPへ]
2003/07/18 楽々サイズ調整
さて、QCanvasViewの用意が整い、これで、FreeNoteの下地となる外観ができあがるぞ!と、実行させてみたところ…
いくつかのGPLソースには、setGeometryでサイズを調整しているものがあったのですが、
SL-C760などの画面の大きさやレイアウトが勝手に切り替わる環境を踏まえて、部品の配置は、レイアウトマネージャで行うこととしました。
[TOPへ]
2003/07/18 QCanvasを使ってみる その1
さて、いよいよ描画領域の調整に入ります。
ここで使用するQCanvasの特徴は…
(1).Line, Polygon, Text, Spriteなどの部品(QCanvasItem)の描画を管理。
(2).標準でダブルバッファ処理を行う。
(3).QWidgetよりも高速。
です。
また、座標管理もキャンバス内で行えるため、Java版のように、今、スクロールバーがどの値なので、
原点からnドットずらして表示なんていう七面倒臭い処理はしなくて済みそう。
(1).描画の途中の軌跡をどう管理するか?
(2).QCanvasをリサイズした際のメモリコストは、どれくらいか?
ということです。
FreeNoteは、際限なくどこまでも描ける感覚が重要なため、例えば、10000 x 10000のキャンバスだと全く動きません!
という話になると、結構厳しい…
#空想が膨らみます。
[TOPへ]
2003/07/18 QCanvasを使ってみる その2
QCanvasを使ってみる その1で、気がかりだ。と言っていた件について実験君 & 確認してみました。
QWidgetであれば、QPainterクラスを使用して、そのままダブルバッファに描画するだけです。
QPainterを利用するには、QPaintDeviceのサブクラスである必要がありますが、QCanvasは残念ながら、そうではありません。
1.ペンが動いている(mouseMoved)うちは、QCanvasLineを追加する。
#あらかじめ、QList
#参考ソースを眺めているうちに気づいたのですが、QWidgetに描画しているにもかかわらず反応が良いソフトもあります。
#遅いのは、私の実装に問題があったという事みたいです。(T-T)
最初、私は、QCanvasは空間の定義だけ管理しており、サイズを大きくしてもメモリを食わないのではないか?と考えていました。
が、どうやらそうではないようです。
Qtのスクロールバーの対応範囲は、100000ポイントなので、できれば限界近くまで行って欲しかったのですが、
このあたりが限界みたいです。
2003/07/21 途中で反応が落ちる?
前回まで、FreeNoteの描画部分は、QCnavasを利用する事にしていました。
これは、QCanvasがQCanvasItemという描画アイテムを管理し、ダブルバッファやらなんやらを制御してくれていたためで、
管理するのが楽そうなのと、QWidgetよりもQCanvasの描画が速いということからでした。