カスタム シグナルは signal の下に記述する必要があり、戻り値は void です。宣言するだけで済み、実装する必要はありません。パラメーターを含めることができ、オーバーロードすることができます。スロット関数の初期バージョンは public スロットに記述する必要があり、拡張バージョンは public または global に記述することができます。戻り値は void であり、宣言 (処理) する必要があり、(cpp で) 実装する必要があります。パラメータを持つことができ、オーバーロードすることができます。使用する際はシグナルとスロットを接続し、トリガー(エミット)を与える必要があります。
今回の条件は、授業後、私が信号を送信する --> お腹が空いた --> 友達が信号を受信 --> 応答して夕食に招待する です。今回は 2 つのクラスが必要です。My クラスと Friend クラスです。それぞれ、私と私の友人に対応します。今回はパラメータを使用した操作のみが実行されます。プロセス:
① まず、QObject に属する 2 つのクラスを追加し、それぞれ My と MyFriend という名前を付けます。
② widget.h でオブジェクトと解除シグナルを宣言
// 对象声明
My * my;
MyFriend * fri;
void classover();
③ firend.h でのスロット関数宣言
public:
explicit MyFriend(QObject *parent = nullptr);
// 槽函数:早期版本必须写到public slots下 高级版本可以写到public或者全局下
// 返回值void,需要声明(treat),需要实现(cpp中)
// 可以有参数,可以发生重载
void treat(QString foodName);
④my.hでシグナルを宣言する
signals:
// 自定义信号 写到signal下
// 返回值是 void ,只需要声明,不需要实现
// 可以有参数,可以重载
void hungry(QString foodName); // 说饿了并且说吃什么
⑤friend.cppに関数を定義
void MyFriend::treat(QString foodName)
{
// 把QString转换成 char * 形式在输出的foodname就不会带""
// 先用(.toUtf8)转成QByteArray(字节数组型)再(.data())转char *
qDebug()<<"我朋友请我吃饭,我要吃:" << foodName.toUtf8().data();
}
⑥ widget.cpp で接続します。
(1) 私と友達のオブジェクトを作成する
// 创建一个我的对象
this->my = new My(this); // 指定好父类后,new之后就不需要管释放了
// 创建一个朋友的对象
this->fri = new MyFriennd(this);
(2) 授業外退出機能の創設
void Widget::classover()
{
// 下课后函数,调用后 触发我饿了的信号
// 触发的关键字 emit
emit my->hungry("肥牛鱼粉");
}
(3) カスタム信号とスロットをパラメーターで接続する
// 连接含参的 信号和槽
// 指针可以指向地址,函数指针指向函数地址
void( My:: *mySingal )(QString) = &My::hungry;
void( MyFriend:: *friSlot )(QString) = &MyFriend::treat;
connect(my,mySingal,fri,friSlot);
(4) ボタンの設定と接続
// 点击 下课按钮 触发下课
QPushButton * btn = new QPushButton("下课",this);
this->resize(600,400); // 重置窗口大小,resize是窗口this下的方法
// 点击按钮,触发下课
connect(btn,&QPushButton::clicked,this,&Widget::classover); // 信号连接槽
(5) テスト
[クラスから抜け出す] ボタンをクリックし、アプリケーション バーの出力を観察します。
補足部分:
①信号接続信号
connect(te,teacherSingal,st,studentSlot);
connect(btn,&QPushButton::clicked,my,mySingal);
// 先连接 friSlot 和 mySingal ,再连接 mySingal 和 &QPushButton::clicked
// ① 在触发QPushButton::clicked(点击按钮)时 ② 通过中介 mySingal ③ 触发 friSlot
②切断
// 断开 friSlot 和 mySingal 之间的连接
disconnect(my,mySingal,fri,friSlot);
注: ① 信号は 1 つの信号に接続できます; ② 信号は複数のスロット機能に接続できます; ③ 複数の信号は 1 つのスロット機能に接続できます;
④信号関数とスロット関数のパラメータの種類は 1 つずつ一致する必要があります; ⑤信号パラメータの数 ≥ スロット関数のパラメータの数。
③ラムダ式:
無名関数オブジェクトの定義と作成に使用され、基本的な形式は次のとおりです。
connect(btn,&QPushButton::clicked,this,[x](){
});
1. [ x ] は式の先頭なので省略できません。x の値は次のとおりです。
(1) [=] は、値の転送方法です。これは、スコープのスコープ内にあるすべての可視ローカル変数を使用できることを意味します。これには、最も一般的に使用される方法が含まれますが、以下の方法は一般的に使用されません。
(2) [=] の効果は [&] と同等です。& は参照渡しの方法を表します。
(3) [this] ラムダが配置されているクラスのすべてのメンバー変数を関数の本体で使用できます。
(4) [a] a を値で渡します。{} 内に渡すことができるのは a のみで、他の変数は認識されません。通常、メンバーの 1 つだけを変更する場合に使用されます。[&b] b を参照によって渡します。
(5) [=,&a,&b] ただし、a、b は参照によって渡され、その他は値によって渡されます。
(6) [=, a, b] a, b 以外は参照値渡し、その他は参照渡し。
2. 関数の戻り値: -> 戻り値の型。前後のデータ型は一致している必要があります。
3. 実装本体 { } の内容は実装が必要な部分であり、slot 関数の中にシグナル関数をたくさん入れるのと同じです。