Cuatro métodos de escritura y cinco métodos de enlace de la ranura de señal de QT

Tabla de contenido

Cuatro métodos de escritura de ranura de señal:

Cinco métodos de conexión:

Ejemplo:

Errores comunes y correcciones:

Error 1: Señal y ranura no conectadas

Error 2: falta de coincidencia de los parámetros de la señal y la ranura

Error 3: No usar la macro Q_OBJECT

Error 4: conexión de subprocesos cruzados no controlada


 

En Qt, las señales (Signal) y los slots (Slot) son un mecanismo de comunicación entre objetos, que se utiliza para lograr un enfoque débilmente acoplado. Cuando se envía una señal, se llama a su ranura asociada. Los siguientes son cuatro métodos comunes de escritura de ranuras de señal y cinco métodos de conexión:

Cuatro métodos de escritura de ranura de señal:

  1. Enlace de función directa :

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

    Esta es la sintaxis de conexión temprana de Qt, que utiliza cadenas para representar señales y ranuras. La comprobación de tipos no se puede realizar en tiempo de compilación.

  2. Conexión del puntero de función :

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

    Este tipo de conexión se verifica en el momento de la compilación, pero puede no ser lo suficientemente flexible en algunos casos, como conectarse a una ranura de clase base.

  3. Concatenación de expresiones lambda (C++11 y versiones posteriores):

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

    Este método puede usar la expresión Lambda como implementación de la ranura, lo cual es muy conveniente.

  4. Qt5 nueva conexión de sintaxis :

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

    Esta sintaxis se introdujo en Qt5 y permite especificar el tipo de conexión, por ejemplo Qt::AutoConnection, , Qt::DirectConnectionetc.

Cinco métodos de conexión:

  1. Autoconexión : seleccione automáticamente el método de conexión de acuerdo con el hilo donde se encuentran la señal y la ranura. Si está en el mismo subproceso, use DirectConnectionotra cosa QueuedConnection.

  2. DirectConnection : cuando se envía la señal, se llama directamente a la función de ranura. Se aplica a la situación en la que las señales y las ranuras están en el mismo hilo.

  3. QueuedConnection : coloque la señal en la cola de eventos del subproceso del receptor, que será procesada por el subproceso del receptor en el momento adecuado. Adecuado para comunicación entre hilos.

  4. BlockingQueuedConnection : QueuedConnectionsimilar, pero el subproceso que envía la señal está bloqueado hasta que el subproceso receptor haya procesado la señal.

  5. UniqueConnection : asegúrese de que la conexión sea única, evitando múltiples conexiones a la misma señal y ranura. Si ya existe la misma conexión, no se creará la nueva conexión.

Ejemplo:

Una aplicación Qt simple que contiene un botón y un cuadro de texto. Cuando se hace clic en el botón, el cuadro de texto muestra un mensaje. Mostraremos cómo usar el mecanismo de ranura de señal de Qt en este caso, cubriendo cuatro formas de escritura y cinco formas de conexión.

#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"

En este caso, creamos una ventana simple que contiene un botón y un campo de texto de solo lectura. Conectamos la clickedseñal del botón a la ranura que muestra el mensaje de cuatro maneras diferentes showMessage.

Errores comunes y correcciones:

Ilustremos algunos errores comunes cuando se trata de señales y ranuras de Qt, y mostremos cómo solucionarlos:

Error 1: Señal y ranura no conectadas

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

Método de corrección:

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

Error 2: falta de coincidencia de los parámetros de la señal y la ranura

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

Método de corrección:

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

Error 3: No usar Q_OBJECTmacros

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

Método de corrección:

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

Error 4: conexión de subprocesos cruzados no controlada

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

Método de corrección:

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

Supongo que te gusta

Origin blog.csdn.net/clayhell/article/details/132202909
Recomendado
Clasificación