Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Qt Signal-Slot Connection Types Explained

Tech May 13 2

Signal-Slot Connection Types in Qt

Connection Type Overview

Qt provides several connection types that determine how slot functions are invoked when signals are emitted:

  • Qt::DirectConnection - Immediate invocation
  • Qt::QueuedConnection - Asynchronous invocation
  • Qt::BlockingQueuedConnection - Synchronous invocation
  • Qt::AutoConnection - Default connection type
  • Qt::UniqueConnection - Single connection enforcement

Key Concepts

The connection type determines the behavior when a slot function is called:

  • Each thread maintains its own event queue
  • Threads receive signals through their event queues
  • Signals are processed within event queues

Implementation Examples

Receiver Class Definition


#ifndef RECEIVER_H
#define RECEIVER_H

#include <QObject>

class Receiver : public QObject
{
    Q_OBJECT
public:
    explicit Receiver(QObject *parent = nullptr);
    
protected slots:
    void handleSignal();
};

#endif

Receiver Implementation


#include "Receiver.h"
#include <QDebug>
#include <QThread>

Receiver::Receiver(QObject *parent) : QObject(parent)
{
}

void Receiver::handleSignal()
{
    qDebug() << "Receiver::handleSignal() thread ID=" << QThread::currentThreadId();
}

Emitter Thread Definition


#ifndef EMITTERTHREAD_H
#define EMITTERTHREAD_H

#include <QThread>

class EmitterThread : public QThread
{
    Q_OBJECT
public:
    explicit EmitterThread(QObject *parent = nullptr);
    
signals:
    void customSignal();
    
protected:
    void run() override;
};

#endif

Emitter Thread Implementation


#include "EmitterThread.h"
#include <QDebug>

EmitterThread::EmitterThread(QObject *parent) : QThread(parent)
{
}

void EmitterThread::run()
{
    qDebug() << "EmitterThread::run() thread ID=" << QThread::currentThreadId();

    for(int count = 0; count < 2; count++)
    {
        qDebug() << "EmitterThread::run() iteration=" << count;
        sleep(1);
    }
    
    emit customSignal();
    qDebug() << "EmitterThread::run() completed";
}

Connection Type Demonstrations


#include <QCoreApplication>
#include "Receiver.h"
#include "EmitterThread.h"
#include <QDebug>

void demonstrateDirectConnection()
{
    static Receiver receiver;
    static EmitterThread emitter;
    QObject::connect(&emitter, SIGNAL(customSignal()), 
                    &receiver, SLOT(handleSignal()), 
                    Qt::DirectConnection);

    emitter.start();
    emitter.wait(5000);
    emitter.quit();
}

void demonstrateQueuedConnection()
{
    static Receiver receiver;
    static EmitterThread emitter;
    QObject::connect(&emitter, SIGNAL(customSignal()), 
                    &receiver, SLOT(handleSignal()), 
                    Qt::QueuedConnection);

    emitter.start();
    emitter.wait(5000);
    emitter.quit();
}

void demonstrateBlockingQueuedConnection()
{
    static Receiver receiver;
    static EmitterThread emitter;
    QObject::connect(&emitter, SIGNAL(customSignal()), 
                    &receiver, SLOT(handleSignal()), 
                    Qt::BlockingQueuedConnection);

    emitter.start();
    emitter.wait(5000);
    emitter.quit();
}

void demonstrateAutoConnection()
{
    static Receiver receiver;
    static EmitterThread emitter;
    QObject::connect(&emitter, SIGNAL(customSignal()), 
                    &receiver, SLOT(handleSignal()), 
                    Qt::AutoConnection);

    emitter.start();
    emitter.wait(5000);
    emitter.quit();
}

void demonstrateUniqueConnection()
{
    static Receiver receiver;
    static EmitterThread emitter;
    QObject::connect(&emitter, SIGNAL(customSignal()), 
                    &receiver, SLOT(handleSignal()), 
                    Qt::UniqueConnection);
    QObject::connect(&emitter, SIGNAL(customSignal()), 
                    &receiver, SLOT(handleSignal()), 
                    Qt::UniqueConnection);

    emitter.start();
    emitter.wait(5000);
    emitter.quit();
}

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);
    
    qDebug() << "Main thread ID=" << QThread::currentThreadId();

    // Uncomment one connection type to test
    // demonstrateDirectConnection();
    // demonstrateQueuedConnection();
    // demonstrateBlockingQueuedConnection();
    // demonstrateAutoConnection();
    demonstrateUniqueConnection();

    return app.exec();
}

Connection Type Behavior Analysis

Qt::DirectConnection - Immediate Invocation

The slot function is called directly in the thread that emits the signal, equivalent to real-time function calling.


// Output example:
// Main thread ID= 0x1abc
// EmitterThread::run() thread ID= 0x191c
// EmitterThread::run() iteration= 0
// EmitterThread::run() iteration= 1
// Receiver::handleSignal() thread ID= 0x191c
// EmitterThread::run() completed

Qt::QueuedConnection - Asynchronous Invocation

The signal is posted to the target thread's event queue and processed by that thread, while the current thread continues execution.


// Output example:
// Main thread ID= 0x1aec
// EmitterThread::run() thread ID= 0x1b5c
// EmitterThread::run() iteration= 0
// EmitterThread::run() iteration= 1
// EmitterThread::run() completed
// Receiver::handleSignal() thread ID= 0x1aec

Qt::BlockingQueuedConnection - Synchronous Invocation

The signal is posted to the target thread's event queue, and the current thread waits for the slot function to return before continuing exectuion. The target thread must be different from the current thread.


// Output example:
// Main thread ID= 0x18c4
// EmitterThread::run() thread ID= 0x1bf8
// EmitterThread::run() iteration= 0
// EmitterThread::run() iteration= 1
// Receiver::handleSignal() thread ID= 0x18c4
// EmitterThread::run() completed

Qt::AutoConnection - Default Connection

This is the default connection type and the most commonly used in Qt applications.


// Output example:
// Main thread ID= 0x1988
// EmitterThread::run() thread ID= 0x1970
// EmitterThread::run() iteration= 0
// EmitterThread::run() iteration= 1
// EmitterThread::run() completed
// Receiver::handleSignal() thread ID= 0x1988

Qt::UniqueConnection - Single Connection Enforcement

Functions identically to AutoConnection but ensures that the same signal can only be connected to the same slot function once, preventing multiple connections.


// Output example:
// Main thread ID= 0x37c
// EmitterThread::run() thread ID= 0x1b70
// EmitterThread::run() iteration= 0
// EmitterThread::run() iteration= 1
// EmitterThread::run() completed
// Receiver::handleSignal() thread ID= 0x37c

Tags: qtSignals

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

SBUS Signal Analysis and Communication Implementation Using STM32 with Fus Remote Controller

Overview In a recent project, I utilized the SBUS protocol with the Fus remote controller to control a vehicle's basic operations, including movement, lights, and mode switching. This article is aimed...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.