まずはシグナルとスロット(Signal & Slot)の基本概念
1. 信号とスロットを理解する
(1) シグナル (Signal): 特定の状況で発行されるイベント。たとえば、PushButton の最も一般的なシグナルは、マウスがクリックされたときに発行される clicked() シグナルです。 (2) スロット (Slot): 関数信号に応答します
。スロットは一般的な C++ 関数と同じ関数であり、クラス (パブリック、プライベート、またはプロテクト) の任意の部分で定義でき、任意のパラメーターを持つことができ、直接呼び出すこともできます。
オブジェクト間の通信を実現するのがシグナルとスロットです。オブジェクトが変化するとシグナルを送信して他のオブジェクトに通知し、別のオブジェクトがシグナルを受信すると機能を実行します。この機能をスロットと呼びます。簡単に言うと、「パブリッシュ-サブスクライバー」モデルです。
信号とスロット関数のバインドを実現するには、次の手順を実行する必要があります。
(1) このスロット関数をヘッダー ファイルで宣言します。
(2) このスロット関数を .cpp ファイルに定義します。つまり、実行する必要があるアクティビティの内容を書き留めます。
(3) connect() 関数を使用して、.cpp ファイルのコンストラクターでシグナルとスロットを接続します。
2. 信号とスロットの自動バインド
(connect() 関数の使用に加えて、connect() を使用せずにシグナルとスロットを自動的に接続することもできます。ただし、スロット関数名は、たとえば: on_function name_clicked に設定する必要があります)
たとえば、設計された UI インターフェイスで、マウスをプッシュボタンの上に置き、右クリックして、[スロットに移動...] を選択します。
このとき、以下の画面が表示されますので、ボタンのクリックが有効な場合は、click()を選択し、OKをクリックしてください。この時点で、次の関数が自動的に生成されます。
void Dialog::on_MyButton_clicked()
{
//添加自己的业务逻辑
}
3. 信号とスロットの手動バインド
(1) シグナルの宣言
signals:
void mysignal_1();
void mysignal_2(int data);
QT には多くのコントロールが付属しており、これらのコントロール自体がボタン clicked()、pressed() などの多くのシグナルを定義します。
(2) スロット宣言
public slots:
void myslot_1();
void myslot_2(int data);
(3) 信号とスロットのバインディング
connect(sender, SIGNAL(signals), receiver, SLOT(slot));
(4) 送信信号
emit mySignal_1(); // 发射信号mySignal_1
(5) 信号とスロットの接続規則
(5.1) 信号パラメータはスロット機能以上のものにすることができ、またその逆も可能です
(5.2) 信号は複数のスロットに接続できます
(5.3) 複数の信号を 1 つのスロットに接続できます
(5.4) 信号を別の信号に接続できます
2、例
Qt Creatorでプロジェクトを作成します。
1、メインウィンドウ.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
int a = 0;
signals: //声明信号
void mySignal_1();
void mySignal_2(int data);
public slots: //声明槽函数
void mySlot_1();
void mySlot_2(int data);
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
2、メインウィンドウ.cpp
#include <QDebug>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->setText("Hello World");
//信号与槽的连接
connect(this, SIGNAL(mySignal_1()), this, SLOT(mySlot_1()));
connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(mySlot_1()));
//发射信号
emit mySignal_1();
}
MainWindow::~MainWindow()
{
delete ui;
}
//槽函数的实现
void MainWindow::mySlot_1(){
qDebug() << "call mySlot_1()";
emit mySignal_2(10000);
}
//槽函数的实现(统计按下按钮次数,并在输出显示中输出)
void MainWindow::mySlot_2(int data){
qDebug() << "call mySlot_2(), data:" << data;
a++;
qDebug() << "第" << a << "次按下按钮";
}
//这个pushButton_clicked方法,直接在ui界面右键转到槽就可以自动生成
void MainWindow::on_pushButton_clicked(){
qDebug() << "on_pushButton_clicked()";
}
3. 実行結果:
(1) プログラムが開始されると、次の出力が表示されます: call mySlot_1()
(2) ボタンをクリックすると、次のように出力されます。
(3) 次に、signal_2 を slot_2 に関連付けます (connect には int などの型のみがあり、パラメーターはありません)
connect(this, SIGNAL(mySignal_2(int)), this, SLOT(mySlot_2(int)));
実行結果は以下の通りです。
参考: