Four writing methods and five linking methods of QT's signal slot

Table of contents

Four signal slot writing methods:

Five connection methods:

Example:

Common errors and corrections:

Mistake 1: Unconnected signal and slot

Mistake 2: Mismatch of signal and slot parameters

Mistake 3: Not using the Q_OBJECT macro

Error 4: Unhandled cross-thread connection


 

In Qt, signals (Signal) and slots (Slot) are a mechanism for communication between objects, used to achieve a loosely coupled approach. When a signal is sent, its associated slot is called. The following are four common signal slot writing methods and five connection methods:

Four signal slot writing methods:

  1. Direct function linkage :

    QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));

    This is Qt's early connection syntax, using strings to represent signals and slots. Type checking cannot be done at compile time.

  2. Function pointer connection :

    QObject::connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot);

    This type of connection is type-checked at compile time, but may not be flexible enough in some cases, such as connecting to a base class slot.

  3. Lambda expression concatenation (C++11 and later):

    QObject::connect(sender, &SenderClass::signal, [=]() { /* slot implementation */ });

    This method can use Lambda expression as the implementation of the slot, which is very convenient.

  4. Qt5 new syntax connection :

    QObject::connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot, Qt::ConnectionType);

    This syntax was introduced in Qt5 and allows specifying the connection type, eg Qt::AutoConnection, , Qt::DirectConnectionetc.

Five connection methods:

  1. AutoConnection : Automatically select the connection method according to the thread where the signal and slot are located. If on the same thread, use DirectConnectionotherwise QueuedConnection.

  2. DirectConnection : When the signal is sent, the slot function is called directly. Applies to the situation where signals and slots are in the same thread.

  3. QueuedConnection : Put the signal into the event queue of the receiver thread, which will be processed by the receiver thread at an appropriate time. Suitable for cross-thread communication.

  4. BlockingQueuedConnection : QueuedConnectionSimilar, but the thread that sends the signal is blocked until the receiver thread has processed the signal.

  5. UniqueConnection : Ensure that the connection is unique, preventing multiple connections to the same signal and slot. If the same connection already exists, the new connection will not be created.

Example:

A simple Qt application that contains a button and a textbox. When the button is clicked, the textbox displays a message. We will show how to use Qt's signal-slot mechanism in this case, covering four ways of writing and five ways of connecting.

#include <QtWidgets>

class MyWidget : public QWidget {
    Q_OBJECT

public:
    MyWidget(QWidget *parent = nullptr) : QWidget(parent) {
        QVBoxLayout *layout = new QVBoxLayout(this);

        button = new QPushButton("Click Me", this);
        textEdit = new QTextEdit(this);
        textEdit->setReadOnly(true);

        layout->addWidget(button);
        layout->addWidget(textEdit);

        connectUsingDirectFunction();
        connectUsingFunctionPointer();
        connectUsingLambda();
        connectUsingQt5Syntax();
    }

private slots:
    void showMessage() {
        textEdit->append("Button clicked!");
    }

private:
    QPushButton *button;
    QTextEdit *textEdit;

    void connectUsingDirectFunction() {
        QObject::connect(button, SIGNAL(clicked()), this, SLOT(showMessage()));
    }

    void connectUsingFunctionPointer() {
        QObject::connect(button, &QPushButton::clicked, this, &MyWidget::showMessage);
    }

    void connectUsingLambda() {
        QObject::connect(button, &QPushButton::clicked, [=]() {
            textEdit->append("Button clicked using lambda!");
        });
    }

    void connectUsingQt5Syntax() {
        QObject::connect(button, &QPushButton::clicked, this, &MyWidget::showMessage, Qt::AutoConnection);
    }
};

int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    MyWidget widget;
    widget.show();

    return app.exec();
}

#include "main.moc"

In this case, we created a simple window containing a button and a read-only text field. We connected the button's clickedsignal to the slot that displays the message in four different ways showMessage.

Common errors and corrections:

Let's illustrate some common mistakes when it comes to Qt's signals and slots, and show how to fix them:

Mistake 1: Unconnected signal and slot

// 错误示例 QObject::connect(button, SIGNAL(clicked()), this, SLOT(showMessage())); // 没有连接按钮的clicked信号与槽函数

Correction method:

// 正确示例 QObject::connect(button, &QPushButton::clicked, this, &MyWidget::showMessage);

Mistake 2: Mismatch of signal and slot parameters

// 错误示例 class MyWidget : public QWidget { Q_OBJECT public slots: void slotWithInt(int value); }; // ... QObject::connect(sender, SIGNAL(someSignal()), this, SLOT(slotWithInt(QString))); // 参数不匹配

Correction method:

// 正确示例 class MyWidget : public QWidget { Q_OBJECT public slots: void slotWithInt(int value); }; // ... QObject::connect(sender, SIGNAL(someSignal(int)), this, SLOT(slotWithInt(int))); // 参数匹配

Mistake 3: Not using Q_OBJECTmacros

// 错误示例 class MyWidget : public QWidget { public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} public slots: void showMessage() { /* ... */ } };

Correction method:

// 正确示例 class MyWidget : public QWidget { Q_OBJECT public: MyWidget(QWidget *parent = nullptr) : QWidget(parent) {} public slots: void showMessage() { /* ... */ } };

Error 4: Unhandled cross-thread connection

// 错误示例 QObject::connect(sender, SIGNAL(someSignal()), receiver, SLOT(slotInDifferentThread())); // 未处理跨线程连接

Correction method:

// 正确示例 QObject::connect(sender, SIGNAL(someSignal()), receiver, SLOT(slotInDifferentThread()), Qt::QueuedConnection); // 使用Qt::QueuedConnection来处理跨线程连接

Guess you like

Origin blog.csdn.net/clayhell/article/details/132202909