C++でQTアプリ(その4) ファイルの選択
ディレクトリを移動してファイルを選択する。下のプログラムではカレントディレクトリの内容をQListViewにリストを表示する。リスト中ディレクトリを選択した場合はディレクトリ移動を行って、その内容をリスト表示。
ディレクトリ関係の処理はQDirクラスを使用。更にQdir.entryInfoList()とQFileInfoListおよびQFileInfoListIteratorを用いることでディレクトリ下の各要素各々に対して処理を行うことが可能、RubyのDir.each{|file| … }と同じ感じ。関数makeFileList()は、リファレンスの例題をそのまま使用した。
const QFileInfoList *list = d.entryInfoList(); QFileInfoListIterator it( *list ); // リストイテレータの作成 QFileInfo *fi; // 走査を行うポインタ while ( (fi=it.current()) ) { // 各ファイルに対し... 処理 ++it; // リストの次の要素へ進む }
ファイル名についてはQStringを用いているせいかUTF-8な日本語でも問題なく処理してくれた。
QDir.setSortingの設定はQListView側で勝手にソートしてしまうので意味を成さない。QListView側でもう一つカラムを追加してQListView.insertItem毎にインクリメントする数値を設定していけば良いと思う。
C++でQTアプリ(その3) 正規表現
Rubyほどの機能は無いようだけれども、QTでもQRegExpクラスを用いることで正規表現によるパターンマッチングが可能みたい。下のプログラムではRegExp欄に正規表現、String欄に文字列を入力してボタンを押すとマッチした文字列を表示する。
QTの正規表現の詳細はリファレンスを参照。このクラスは日本語の文字も認識してくれるのは便利です、ただし\sで全角スペースの認識は無理だけど。。。
それとは別に、結果を表示する為の関数printを定義して日本語と半角英数字を別に出力させると、まず英数字が全部まとめて出力されてから日本語がまとめて出力というように順番が狂って出力されてしまった、原因は不明???
そのため日本語と英数字を一個のQStringにしてから出力させるようにしたら上手くいった。
C++でQTアプリ(その2) シグナルの追加
昨日のプログラムにシグナルを追加してみる。
hello.hでシグナルpbPressed()を宣言、シグナルの発生はemitを使うみたい。ボタンを押したら呼ばれるスロットでこのシグナルを発生するようにして、connectで新しいスロットslot_pbPressed()と結合させる。
これでボタンを押すとslot_pb()が呼ばれて、更にslot_pbPressed()が呼ばれるようになった。
hello.h
signals: void pbPressed(); private slots: void slot_pb(); void slot_pbPressed();
hello.cpp
QObject::connect( this, SIGNAL(pbPressed()), this, SLOT(slot_pbPressed()) ); void Hello::slot_pb() { eb->insertLine(tr("ボタンを押した")); emit pbPressed(); } void Hello::slot_pbPressed() { eb->insertLine(tr("シグナルpbPressed発生")); }
C++でQTアプリ(その1) シグナルとスロット
勉強としてdev-img1.6環境でC++を使ってHello Worldよりましなプログラムを書いてみる。とりあえずボタンを押すとテキストエリアに文字を書くプログラム。
QT部分はRuby/Qteの知識で何とかなりそうなんだけど、C++の書き方がよくわからない。
気付いたポイント
- クラスの定義はmain.cppと別のファイルにする、下のプログラムを一個のファイルに書いてコンパイルしたらVirtual何とかが定義されていないというエラーになった。
- 変数の宣言について以下の様に2種類の方法があるけど、後者の方が良いらしい。でも前者の方法でしか書けないものもある(書き方を知らないだけ?)
QLabel label(); label.setText(); QLabel *label = new QLabel(); // *がクラス側にくっついている場合もある、違いは??? label->setText();
- 自分でスロットを定義する場合はヘッダーファイルの「Q_OBJECT」行が必要らしい
- ヘッダーファイルには#ifndef〜#endifの記述が必要らしい(二重宣言の防止?)
- cppファイルで使用していない変数をヘッダーファイルで宣言していると妙なことになる場合があるので注意
- コンパイル時のエラーはproファイルやMakefileも疑う。(cppの#includeに"xxx.cpp"と書いてあり不適切なproファイルになっていて一日中ハマッてしまった)
Cygwin上のクロスコンパイル環境
最初にググってみつけた幾つかのサイトを参考にgcc3系のザウルス用クロスコンパイル環境を構築しようと思ったのだけど、どうも上手くいかない。諦めてgcc2.95系の環境を構築。
QtopiaSDK on Cygwinに記述されている内容をそのまま実行。
ファイルの入手先
- http://downloads.sourceforge.jp/zaurus-ja/1999/から、 binutils-cross-arm-2.13.i386-cygwin-20030106.tar.bz2とgcc-cross-sa1100-2.95.3-i386-cygwin-20030106.tar.bz2
- http://developer.ezaurus.com/sl_j/tool/tools.htm#Linuxからlinux-headers-arm-sa1100-2.4.6-3.i386.rpmとglibc-arm-2.2.2-0.i386.rpm
- クロス開発環境の構築からqtopia-free-1.5.0-1.i386.rpmとqtopia-free-1.5.0-1.src.rpm
- http://prdownloads.sourceforge.jp/zaurus-ja/9566/からqtopiasdk-gcc33-i386-cygwin-20040517.tar.bz2
- http://developer.ezaurus.com/sl_j/doc/reference.htmからlibqte.so.2.3.2.gzとsharpsdk-pub-20021227.tar.gz
- http://downloads.sourceforge.jp/zaurus-ja/1998/からtmake-conf-cygwin.tar.bz2とconfig-examples.tar.gz
qtopia-free-1.5.0-1.src.rpmはrpmコマンドで展開できなかったので、Windows上のツールで展開してqtopia-free-1.5.0.tar.gzを取得。
追記
/opt/Qtopia/tmake/lib/qws/linux-sharp-g++/tmake.sonfを要修正(qpeを追加)
TMAKE_LIBS_QT = -lqte -lqpe TMAKE_LIBS_QT_THREAD = -lqte-mt -lqpe-m ←こちらは自信なし
環境変数の設定、dev-arm-qpe.shの実行は頭の「.」(ピリオド)を忘れずに
$ . ~/SLZaurus/bin/dev-arm-qpe.sh
あとは、progen→tmake→makeでコンパイル
Cygwin上でのエミュレーション環境は上手く動作しませんでした。なぜかstartx_qvfbでX+twmが起動せず、別途Xを起動してstartqpeすると何とかdllが無いと怒られました。
QtopiaのサンプルプログラムとZEditorは上記の環境で動作しました、流石にPC上だとコンパイルが早いですねー
hello.cをprogen,tmakeでmakeするとエラーになったので作成したMakefileのLIBS行の「-lqte」を削除する。
以下、自分用に参考先の内容を丸ごとコピー
クロスコンパイラ $ cd / $ tar xvjf binutils-cross-arm-2.13.i386-cygwin.tar.bz2 $ tar xvjf gcc-cross-sa1100-2.95.3-i386-cygwin.tar.bz2 クロスコンパイル用ライブラリ類 $ rpm -iv --ignoreos linux-headers-arm-sa1100-2.4.6-3.i386.rpm $ rpm -iv --ignoreos glibc-arm-2.2.2-0.i386.rpm クロスコンパイル用QtopiaSDK展開 $ rpm -iv --ignoreos --nodeps qtopia-free-1.5.0-1.i386.rpm $ mv /opt/Qtopia/bin /opt/Qtopia/bin.linux $ mv /opt/Qtopia/lib /opt/Qtopia/lib.linux エミュ用QtopiaSDK展開(不要?) $ cd / $ tar xvjf qtopiasdk-gcc33-i386-cygwin-20040517.tar.bz2 $ mv /opt/Qtopia/lib.linux/fonts /opt/Qtopia/lib tmake設定ファイル展開 $ cd /opt/Qtopia/tmake/lib/qws $ tar xvzf tmake-sharp.tar.gz $ cd /opt/Qtopia/tmake/lib $ tar xvjf tmake-conf-cygwin.tar.bz2 環境設定ファイル展開 $ mkdir ~/SLZaurus/bin $ cd ~/SLZaurus/bin $ tar xvzf config-examples.tar.gz シャープライブラリインストール $ tar xvzf sharpsdk-pub-20021227.tar.gz $ mv /opt/Qtopia/sharp/lib /opt/Qtopia/sharp/lib.bak $ cp -R sharp/lib /opt/Qtopia/sharp/lib $ mv /opt/Qtopia/sharp/lib.bak/fonts /opt/Qtopia/sharp/lib/ $ cp -R include/sl /opt/Qtopia/include/ $ mv /opt/Qtopia/sharp/lib/libqte.so.2.3.2 /opt/Qtopia/sharp/lib/libqte.so.2.3.2.bak $ gunzip libqte.so.2.3.2.gz $ cp libqte.so.2.3.2 /opt/Qtopia/sharp/lib/
dev_img-1.6を試す(その3)
一昨日の続き
squashfsパッケージ内のtmake.confの書き換えができないので必要なファイルを書き換え可能な場所(/hdd3/)にコピーして試してみました。
- /mnt/dev/tmake/lib/qws/linux-sharp-g++/以下のファイルを/hdd3/qws/linux-sharp-g++/にコピー(tmake.confもここに存在)
- /mnt/dev/tmake/lib/unix/以下のファイルを/hdd3/unix/にコピー
- 環境変数TMAKEPATH書き換え
TMAKEPATH=/hdd3/qws/linux-sharp-g++
TMAKE_INCDIR = /mnt/dev/include TMAKE_LIBS_QT = -lqte -lqpe
上の行はzten改など使用していて、compiler_setup.sh実行時の/usr/local/includeのシンボリックリンク作成が失敗しても、cのソースのmakeでのコンパイル時にパスを通す為、ちなみにcのソースをコンパイルする場合は無条件で/usr/local/inclueを見にいくようなのでコマンドラインから直接コンパイルする場合には-Iオプションを指定する必要がある(Zten改使用時)
下の行はQTアプリのデザインをザウルス標準のものにした場合(クラスQPEApplicationを使用等)の設定。
これでprogen、tmakeを使用してMakefileを作成してmakeでコンパイルする様にすればcのソースもc++のソースもコンパイル出来そうです。