序章
シグナルとスロットは、Qt フレームワークの優れたメカニズムの 1 つです。ユーザーがイベントをトリガーすると、ブロードキャストと同様に、目的のない信号(シグナル)が送信されます。オブジェクトがこの信号に関心がある場合、この信号を処理するために接続 (接続) し、関数 (スロットと呼ばれる) をバインドします。つまり、シグナルが送信されると、接続されているスロット関数が自動的に呼び出されます。これは開発モードのオブザーバー モードに少し似ています。つまり、対象のイベントが発生すると、操作が自動的にトリガーされます。
シグナルとスロットは Qt 独自の情報伝達メカニズムであり、Qt 設計プログラムの重要な基盤であり、相互に干渉しないオブジェクトが接続を確立できるようにします。スロットの本質はクラスのメンバー関数であり、そのパラメーターは任意の型にすることができます。通常の C++ メンバー関数とほとんど違いはなく、仮想関数にしたり、オーバーロードしたりすることができます。これは、パブリック、プロテクト、プライベートにすることも、他の C++ メンバー関数によって呼び出すこともできます。唯一の違いは、スロットは信号に接続でき、スロットに接続された信号が送信されるたびにスロットが呼び出されることです。
接続信号スロット接続関数の 5 番目のパラメーター
connect 関数数原型如下:
[static] QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
ConnectionType は Qt 名前空間で定義された列挙であり、具体的な内容は次のとおりです。
enum ConnectionType {
AutoConnection,
DirectConnection,
QueuedConnection,
BlockingQueuedConnection,
UniqueConnection = 0x80
};
- Qt::AutoConnection: デフォルト値。送信者と受信者が存在するスレッドに応じて、いつシグナルが送信されるかを判断します。同じスレッド内の場合は、Qt::DirectConnection を使用して接続し、それ以外の場合は、Qt::QueuedConnection を使用して接続します。なお、この判定は送信側オブジェクトが存在するスレッドとは関係なく、実際に判定されるのはシグナルを送信するアクションが存在するスレッドである。
- Qt::DirectConnection: シグナルの送信時にスロット関数が直接呼び出され、スロット関数はシグナル送信者が配置されているスレッドで実行されます。この効果は、信号が送信された時点でスロット関数が直接呼び出されたように見えます。マルチスレッド環境ではより危険であり、クラッシュを引き起こす可能性があることに注意してください。
- Qt::QueuedConnection: スロット関数は、制御が受信者が配置されているスレッドのイベント ループに戻るときに呼び出され、スロット関数はシグナル受信者が配置されているスレッド上で実行されます。シグナル送信後、スロット関数はすぐには呼び出されず、受信側の現在の関数が実行されてイベント ループに入るまでスロット関数は呼び出されません。これは通常、マルチスレッド環境で使用されます。
- Qt::BlockingQueuedConnection: スロット関数の呼び出しタイミングは Qt::QueuedConnection と同じですが、シグナル送信後、スロット関数の実行が完了するまで、送信側が存在するスレッドはブロックされます。複数のスレッド間の同期が必要です。受信者と送信者が同じスレッドに存在してはいけないことに注意してください。そうしないと、プログラムがデッドロックしてしまいます。
- Qt::UniqueConnection: このフラグは、ビット単位または (|) によって上記の 4 つと組み合わせて使用できます。このフラグが設定されている場合、信号とスロットがすでに接続されている場合、繰り返しの接続は失敗します。つまり、繰り返しの接続は回避されます。
信号とスロットの接続方法
C++ 接続信号スロット - Qt4 構文
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(close()));
C++ 接続信号スロット - Qt5 構文
connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::close)
C++ 接続信号スロット - 関数ポインター
void(MainWindow:: *buttonClickSlot)() = &MainWindow::onButtonPushed;
connect(ui->pushButton, &QPushButton::clicked, this, buttonClickSlot);
C++ 信号スロットの接続 - ラムダ式
connect(ui->pushButton, &QPushButton::clicked, this, [=](){ this->close(); });
QML スロットに接続された C++ 信号
class Test {
signals:
void sendData(QString str);
}
1) グローバル オブジェクトを登録している場合は、接続を使用して接続する必要があります。
Connections {
target: test
onSendData: {
console.log(str)
}
}
2) 登録がクラスの場合は、最初にオブジェクトをインスタンス化し、次に on を直接使用して以下を受け取る必要があります。
Test {
onSendData: {
console.log(str)
}
}
QML 信号は C++ スロットに接続します
#include <QQuickItem>
QObject *quitButton = root->findChild<QObject*>("quitButton");
if (quitButton) {
QObject::connect(quitButton, SIGNAL(clicked()), &app, SLOT(quit()));
}
C++ は QML 関数を呼び出します
QObject *changeBtn = root->findChild<QObject*>("objectName");
if (changeBtn)
{
QMetaObject::invokeMethod(changeBtn, "changeColor");
}
QML は C++ 関数を呼び出します
onClicked:
{
className.test();
}
QML 信号は QML スロットに接続します
// A.qml
Rectangle {
signal sendData(var data)
}
// B.qml
Rectangle {
onSendData: console.log(data)
}
この記事の利点は、 Qt 開発学習教材パッケージ、技術ビデオ (C++ 言語基礎、C++ デザイン パターン、Qt プログラミング入門、QT シグナルとスロット メカニズム、QT インターフェイス開発イメージ描画、QT ネットワーク、QT を含む) を無料で受け取ることです。データベースプログラミング、QTプロジェクト実戦、QSS、OpenCV、Quickモジュール、面接での質問など) ↓↓↓↓下記参照↓↓料金受け取りは記事下部をクリック↓↓