OSのクローズボタンを押したとき:QWidget::closeEvent()が呼ばれる。 ESCキーを押したとき:QDialog::reject()→QDialog::done®の順番に呼ばれる。
http://lists.trolltech.com/qt-interest/2006-06/thread00968-0.html
QAbstractItemModel系を継承して読込み専用(外部のデータソースを参照してItemModelに変換するような場面を想定)のモデルを作る時は、データソースが変更されたタイミングでlayoutChanged()シグナルを発行しなければならない。多分。 さもないと、Viewが更新されなくて超ハマル。丸一日くらいハマル。
恐らく、データソースが更新された事を検知出来ないため、Viewが更新されないんだと思う。
【追記:2009/10/15】 QUiLoaderまたはQFormBuilderを使った方がいいかも?
通常、Designerで作ったUIを含むウィジェットを使うときは
#include <QDialog> #include "ui_MyDialog.h" class LibMyDialog : public QDialog, public Ui::MyDialog { public: LibMyDialog(QWidget *parent = 0) : QDialog(parent) { setupUi(this); .... } .... };
のように多重継承を使って実装するが、汎用ウィジェットとしてライブラリ化しようとした時、この書き方だとui_MyDialog.hに依存する事になり大変美しくない。 代わりに
#include <QDialog> class LibMyDialog : public QDialg { class Ui_MyDialog *mUI; public: LibMyDialog(QWidget *parent = 0) : QDialog(parent) { mUI = new Ui_MyDialog; mUI->setupUI(this); .... } };
という風に書くと、いい感じになる(面倒だったので、ここではヘッダにコンストラクタ書いてるけど、実際はcpp側に実装してね)。 この書き方だとUI部品と名前が衝突する事もないし、通常のアプリでもこっちの書き方の方がいいのかも・・・?
この書き方が正しいかどうかは不明。一応ちゃんと動いてはいるけど。
unixだとdebugビルドの場合でも、リンクされるDLLはリリース用のヤツ(ファイル名に“d”が付いてないヤツ。QtCore4.dllとか)になってしまう模様。 debugビルドなexeを実行しようとすると、assert等のデバッグ用シンボルがリリースDLLに含まれていないため、シンボルが見つからねーとエラーを吐く。emacsでgdbデバッグが出来なかったのもその為だと思われる。
でも、Qt Command Promptからだと実行もgdbも使える。謎。
c:4Qt/2009.02/qt/mkspecs/features/qt_functions.prf の
isEmpty(LINKAGE) { CONFIG(debug, debug|release) { win32:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}d mac:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}_debug } ...
という部分に、
unix:LINKAGE = -l$${LIB_NAME}$${QT_LIBINFIX}d
を追加してやれば、unixモードでもデバッグDLLがリンクされる。 システムファイルを直接書き換えるのは美しくないが、現状これしか対策方法が見あたらない…。
スレッドやRTTI、STLまわりの扱いも違うみたいだが、詳しくは知らない。
CheckBox in QComboBox http://da-crystal.net/GCMS/blog/checkboxlist-in-qt/
自分でslotを作る場合、マクロを使うと危険っぽい。
例えば、次のような処理内容が殆ど一緒のslotを作りたいとする。
void changeState_A(int state) { this→setState('A', state); } void changeState_B(int state) { this→setState('B', state); } void changeState_C(ins state) { this→setState('C', state); }
ここで楽をしようと、クラス宣言内で
public slots: #define SLOT_MAKER(name) void changeState_##name (int state) { 略 } SLOT_MAKER(A); SLOT_MAKER(B); SLOT_MAKER(C);
などと書くと、SLOT_MAKERは展開されず、SLOT_MAKER(…)自体が関数と見なされてmocが生成されてしまう。 超罠。
一手間増えるが、ヘッダではslot関数名をしっかりと記述し、cppの方でマクロで関数を組み立てる分には問題ない。
既存のクラスにQ_OBJECTマクロを追加した場合は、qmakeし直す必要あり。 さもないとコンパイル時に「vtableがふがふが」という、一見意味不明なエラーでハマる事になる。
QString str("hoge"); QByteArray byteArray(str.toAscii()); const char *cStr = byteArray.constData(); // cStr = 'hoge\0'
文字コード?そんなのキニシナイ(・∀・)
DOS窓が開いてもいいなら、QTestのqWait, qSleepが使える。 嫌なら
QTime dieTime = QTime::currentTime().addSecs(5); // 5秒後 while( QTime::currentTime() < dieTime ) QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
こんな感じでおk。addSecs()の代わりにaddMSecs() も使える。
QObject::blockSignals(bool)を使えば実現できるぞ!
connect(HogeListWidget, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(listChanged())); ... HogeListWidget->blockSignals(true); // signalアッチ(・A・)イケ!! HogeListWidget->addItem("Item 1"); // listChanged()は呼ばれない HogeListWidget->blockSignals(false); // signalコッチ(・∀・)コイ!!