Qt
Qt4.5リリース記念
リンク
- 本家
- クラスリファレンス
- 本家フォーラム
- サードパーティアプリ
- Extention Library
- http://calmlight.s2.zmx.jp/index.html 「Qt4 Note」がすばらしく参考になる。
- OFF-SOFT
QtRuby
Qtのビルド
Mingwをインストールしてパスを通したあと、
% configure -platform win32-g++ % mingw32-make
すげえ時間かかる。環境変数LIBとかINCLUDEはクリアしないとMSVCとぶつかるらしい。 これはその後も付きまとうので、上手くいかない場合はLIBとINCLUDEを一度クリアして試すとよい。
IDE
どうも本命はQt Creatorだなあ。
printfデバッグ
qDebug("%d\n",hogehoge);
のようにするとコンソールに表示される。
日本語表示
main.cppに
QTextCodec::setCodecForTr(QTextCodec::codecForLocale()); QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
という呪文を書いておく。Qt Creatorの場合はこれでOk。
Eclipseなどエディタのデフォルトがutf-8の場合は、
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
QTextCodec::setCodecForTr(QTextCodec::codecForName("utf-8"));
で。
お約束のMessageBox
#include <QMessageBox>
...
QMessageBox::StandardButton reply =
QMessageBox::information(this,tr("こんにちは!"), tr("こんにちはこんにちは!"));
...
シグナルとスロット
ウィジェットはシグナルとスロットを持っている。シグナルはイベントみたいなもので、スロットはそれに対応した処理のこと。
たとえば、QpushButtonが押されたらQFileDialogでファイル選択を行って、そのファイル名をQlineEditに伝えたいとする。
- QpushButtonのclicked()シグナルはQWidgetのbutton_clicked()スロットに接続されている
- QWidget::button_clicked() には、QFileDialogの戻り値をQWidget::filename_updated(QString)シグナルに渡す。
- QWidget::filename_updated(QString) シグナルはQlineEdit::setText(QString)スロットに接続されている
という状態にしておけばシグナルが行き渡る。無いスロットやシグナルはhogehoge.h で定義しつつ、QtDesignerの Edit Signal/Slot モードで接続する。QtDesignerで新規に作ったスロットやシグナルが、hogehoge.hに現れないのは もうひとつ気が利かないかんじだが、connectが陽に現れない(ui_hogehoge.hに記述されている)というのは 結構すごいかもしれない。つまりQtDesignerに接続関係がすべて見えているということ。
追記。on_送信元オブジェクト名_シグナル名() というスロットをhogehoge.h とhogehoge.cppに定義するだけで 明示的にQtDesignerでつながなくてもよいらしい。
画像ビューワを作ってみよう
画像を表示するWidgetはQgraphicsViewだが、QGraphicsSceneを作ってsetSceneすればいいらしい。 QGraphicSceneに画像を追加したい場合はPixmapにすればいいらしい。
fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), QDir::homePath().append("/My Documents/My Pictures"),
tr("Image Files (*.png *.jpg *.bmp)"));
pixmap.load(fileName);
scene.addPixmap(pixmap);
ui->graphicsView->setScene(&scene);
うーん、最後にuiを直接叩いてるのがQtらしくないような気が。描画用のスロットをgraphicsViewに追加してシグナルを投げるとか?
ちなみにこのままだと、このコードを呼ぶたびにシーンにロードされたpixmapが追加されていくので、前回追加したpixmapを取り除いてからのほうがいい。
レイアウト
画面サイズ変更に追従するにはレイアウトを用いる。下記参考。 http://pokosho.com/t/qt/designer_tuto/1/index.htm
サウンド
Qsound sound("hoge.wav");
sound.play();
さすがにこの辺はJUCEのほうが充実してるか。
リソース
Qt CreatorのAdd new resource file でリソースファイル追加。ファイルパスの代わりに":ファイルパス"という記法でファイルにアクセスできる。 ただし、QSoundは未対応(という事実に気づかずに数時間無駄にしてしまった)。そのうち対応するらしい。
リリース
リリースビルドしたアプリをQtの入っていないマシン、あるいはパスがちゃんと通っていない状況で実行したときに下記エラーが出ることがある。
プロシージャ エントリ ポイント *** が ダイナミック リンク ライブラリ QtCore4.dll から見つかりませんでした。
結論だけいうと、バイナリと同じ場所に、必要なdllをC:\Qt\2009.01\qt\libからコピーしましょう。 必要なdllはDependency Walkerで見ればわかりますが、mingw10.dll, qtcore4.dll, qtgui4.dll はだいたい必要。
以降詳細。C:\Qt\2009.01\binに入ってるQt系のdllと、C:\Qt\2009.01\qt\libに入っているdllのバージョンが微妙に違うみたい。ビルド時に前提にしてるのは後者なのだが、前者はSDKインストール時にパスを張ったりしてるとそちらが優先される。ああ、これが噂に聞くDLL hellというやつか。結局こうやってアプリごとにDLLをつけて配布するとダイナミックリンクの意味が全然ないのだけど、LGPLで配布したい場合はスタティックリンクはやりたくないし、どんな環境でも安定して動かすとなると直下に置くのが一番かなあ。