Qt のカスタムシグナルとスロット

        カスタム シグナルは 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 関数の中にシグナル関数をたくさん入れるのと同じです。

おすすめ

転載: blog.csdn.net/weixin_58351753/article/details/127460453