hakeの日記

Windows環境でプログラミングの勉強をしています。

coLinux上でQteエミュレーション

最近のザウルス用のQtアプリの勉強はコンパイル速度や画面の広さといった理由でWindowsPC上に構築したCygwin上のクロスコンパイル環境で行うことが多くなっていました。ところが動作確認の段階でいちいちバイナリをザウルスの移動する作業が面倒なのでエミューレションできるqvfbを導入すべくいろいろと努力していたのですがどうも上手くいかない。qvfbの単体起動で「bad systemcall」と表示されるに至ってスッパリと断念、coLinux上にQtのクロスコンパイル環境とエミュレーション環境を作ることにしました。

で、できたのが上の画像、実行しているのは先日のdrawtestのプログラムです。画面がWindowsっぽく無くなっていてなんか嬉しい(笑) ちなみにXサーバーはCygwin/Xを使用しています。
ただし実際に動かしてみると若干の問題点もありますね、挙げると以下のとおり。

  • レイアウトがザウルス上のQt環境と微妙に(かなり?)異なる
  • ソースの中でメッセージ等に日本語を使用していると落ちる(何か対処方法があるのでしょうか)
  • テキストエリアへの入力やボタンを押してからの反応が鈍いことがある(CygwincoLinuxを同時に動かしているせい?)

まぁC++の勉強につかう分にはなんら不満ではないのでこのまま使用してみようと思います。これでCygwinはXサーバー機能以外は必要なくなったかもしれない。
以下、導入手順

続きを読む

C++でQTアプリ(その10) 描画処理

Ruby/Qteの勉強で行ったQPainterを用いた線の描画プログラムを書いてみた。画面下のテキストエリアの関数の定義を書き、Drawボタンを押すと関数の曲線を描きます。
関数の評価の方法がわからない(evalみたいなのはC++にもあるのだろうか)のでslcalcのソースを使わせてもらいました。
描画はQPainter *pを宣言してp->begin()からp->end()の間で描画内容を記述します。今回はX=-319〜319の範囲での定義した関数によるYの値で決まる座標に線を引いています。

続きを読む

C++でQTアプリ(その9) ダイアログの作成

クラスQDialogを使ってダイアログ用サブウィンドウを作成してみる。クラスDlgはQDialogを継承、ボタンAccept、Reject、Closeを配置して各々同名のスロットでウィンドウを閉じるようにしている。またgetStatus関数によってCloseEventの発生を知ることができるようにしてみた。
ダイアログウィンドウはクラスDialogTest上のnewで新規ウィジェットを作成し、execで表示を行い結果を取得している。ちなみにダイアログはモーダルで作成している。
これでウィンドウの閉じ方による返り値とCloseEventの発生の有無を調べてみると以下の様な結果となる。

 OK(右上):Accepted、CloseEventなし
 X(右上):Rejected、CloseEvent発生
 Accept :Accepted、CloseEventなし
 Reject :Rejected、CloseEventなし
 Close  :Rejected、CloseEvent発生

CloseEventはウィンドウを閉じる全ての場合に発生するものでは無いらしい。というかAcceptやRejectは実際にはウィンドウを閉じていない?

続きを読む

C++でQTアプリ(その8) QCopメッセージ送信

昨日作成したrcvqcopにメッセージを送信してみる。
ボタンRaiseを押すとメッセージraise()が送信される、ボタンMessageではtest(QString)が引数付きで送られる。いずれもrcvqcopが起動していない場合はメッセージ受信により起動する。
メッセージの送信にはQCopEnvelopeを使用。リファレンスを見るとQCopChannel::sendでも送信ができそうで実際コンパイルも通ったが動作はしなかった。
なお、通常ターミナルでアプリ起動に使用するメッセージ

QPE/System 'execute(QString)' rcvqcop

を送信してみたがQVGAモードで起動するような素振りをみせたけど起動しなかった。また、メッセージ中に指定している数の引数を付けないでメッセージを送信した場合Qtopiaが落ちたので注意が必要。引数が複数存在する場合は「<<」で接続していく。

続きを読む

C++でQTアプリ(その7) QCopメッセージ受信

ザウルスのQTアプリケーションではQCopを使って相互にメッセージのやりとりを行うことができる、その実験。
クラスQCopChannelを用いてQCopチャンネルを設定、QCopメッセージを受信するとシグナルreceivedが発生するので、connectを用いて処理を行うスロットに接続する。下のプログラムではメッセージtest()またはtest(QString)を受信した場合にその旨を表示、それ以外の場合はUnknownと表示するようにしている。
コンパイルしてできた実行ファイルrcvqcopを/home/QtPalmtop/binの下に置いて適当にアイコン登録して起動。ターミナルからQCopメッセージを送ってみる。

$ qcop QPE/Application/rcvqcop 'test()'
$ qcop QPE/Application/rcvqcop 'test(QString)' 'Send QCop Message'

ちなみにrcvqcop起動時と他のアプリから切り替えたときにはメッセージraise()を受信するのがわかる。

追記

QCopChannnelを使用しない方法もありました、7月28日の日記を参照

続きを読む

C++でQTアプリ(その6) イベント処理

予め用意されているイベントに処理を追加。下のプログラムでは画面をペンでタップすると文字を表示する。
クラスQMultiLineEditを継承して新たにEditというクラスを作成、ここでmousePressEventの処理で“mousePressEvent発生”の文字を挿入するようにしている。ちなみにmousePressEventは、QMultiLineEditの継承を遡ってQWidgetにあるイベントである。ヘッダーファイルでの宣言にvirtualがくっついているのはリファレンスのProtected Membersで書かれていたのでそのとおりにした、理由は不明。

続きを読む

C++でQTアプリ(その5) テキストファイルのアクセス

テキストファイルの読み書きをしてみる。ファイルリードボタンを押すと/home/zaurus/Documents/sjis.txtの内容をテキストエリアebに表示、ファイルライトボタンを押すとテキストエリアの内容を/home/zaurus/Documents/sjis2.txtへ出力する。
アクセスするファイルの文字コードはQTextCodecで指定する。ファイルへのアクセスは QTextStreamを介して行う。ストリームを使用することで行単位の読み込みや「<<」を用いての出力が可能になる。ファイルリードについてはQFileのリファレンスの例題をそのまま使用した。
テキストエリアebの行数が多い場合は、eb->textをストリームにして1行ずつ出力した方が良いのかもしれない。
QTesxtCodecは各スロットではなくコンストラクタで文字コードを定義して使用したかったのだけど、やり方が不明。


以下余談、C++は文字列の扱いが大変っていうイメージがあったのだけれども、QTのクラスを扱う限りではかなりRubyライクなプログラミングができている。これがコンソールアプリを作るとなると、こんなにお気楽にはできないのだろうなぁ。

続きを読む