Qt signal-slot connections - only allow a certain type of connection for a signal

Viewed 93

I have a Qt-based library which has an object that emits signals, but also does some stuff asynchronously behind the scenes.

It is possible for the user of the library to connect the signal being emitted by the object using Qt::DirectConnection or Qt::BlockingQueuedConnection, which will hijack the object's dedicated thread and therefore, and potentially break its functionality.

Is there a way of only allowing for the signal to be connected using a given type of connection? Qt::QueuedConnection, to be specific. Such that the user gets a compilation error when they try to use any other type of connection.

1 Answers

You can use a proxy signal that you declare in the public interface and connect your own internal signals to that signal using queued connection. Thus, the user will be able to use this signal in any way (direct or queued), but it will be already emitted by queued connection.

Since signals can't be private, there is no way to hide them once they are declared in a class. One solution is to use PIMPL to hide your internal signals from the user. The example shows only queued connection between signals, but not the PIMPL:

#include <QObject>

class InternalSignal : public QObject
{
    Q_OBJECT
public:
    explicit InternalSignal(QObject *parent = nullptr) : QObject{parent} {
        connect(this, &InternalSignal::myPIMPLSignal, this, &InternalSignal::mySignal, Qt::QueuedConnection);
    }

signals:
    void mySignal();
    void myPIMPLSignal(); // move this signal to PIMPL class
};
Related