シグナルとスロット
シグナルとスロットの仕組みを少し詳しく追ってみましょう。スライダの値を表示させるコードは,
QSlider* slider = new QSLider;
QLDCNumber* lcdNumber = new lcdNumber;
QObject::connect(slider, SIGNAL(valueChanged(int)),
lcdNumber, SLOT(display(int)));
valueChanged(int)がシグナルで,
スライダを操作して値が42になったときに,
シグナルとスロットのコードの実装方法は次のようになります。
class CustomClass : public QObject
{
Q_OBJECT
signals:
void valueChanged(int);
public slots:
void display(int);
};
シグナルとスロットの仕組みを使うには,
タイプセーフコールバック
Qtのシグナルとスロットという仕組みは,
コールバックは,
connect()による接続が成功するのは2通りの場合があります。
- シグナルとスロットのシグニチャが一致する。
今迄の通りです。 - スロット側の引数が少ない。途中迄は引数の型と順序は一致している。
connect(redSlider, SIGNAL(valueChanged(int)),
this, SLOT(sliderMoved()));
connect(greenSlider, SIGNAL(valueChanged(int)),
this, SLOT(sliderMoved()));
connect(blueSlider, SIGNAL(valueChanged(int)),
this, SLOT(sliderMoved()));
オブジェクトの疎結合とカプセル化
センダーとレシーバーは,
シグナルとスロットの接続の組み合わせ
シグナルとスロットは次の3通りの組み合わせで接続できます。
- シグナルを複数のスロットに接続する
- 複数のシグナルを同じスロットに接続する
- シグナルをシグナルに接続する
connect(slider, SIGNAL(valueChanged(int)),
lcdNumber, SLOT(display(int)));
connect(slider, SIGNAL(valueChanged(int)),
dial, SLOT(setValue(int)));
connect(mainWindow, SIGNAL(message(const QString&)),
logger, SLOT(logging(const QString&)));
connect(findRecord, SIGNAL(erroMessage(const QString&)),
logger, SLOT(logging(const QString&)));
connect(slider, SIGNAL(valueChanged(int)),
this, SIGNAL(valueChanged(int)));
シグナルはblockSignals()でブロックでき,
スレッド間でも使用可能
イベントループへのアクセスがスレードセーフな関数を用いて,
Object::connect(sender, SIGNAL(signal), receiver, SLOT(method), type)
connect()にの5番目の引数typeで,
表1 コネクションタイプ
コネクションタイプ | 説明 |
---|---|
Qt::DirectConnection | シグナルが送信されるとすぐにスロットを呼び出し, |
Qt::QueuedConnection | シグナルが送信されるとシグナルをイベントキューに入れ, |
Qt::BlockingQueuedConnection | QueuedConnectionと同様だが, |
Qt::AutoConnection | レシーバーとセンダーが同一スレッドにあればDirectConnection, |
main()のあるメインスレッド (GUIスレッド) は,
まとめと次回予告
今回は,