Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect QSslSocket::error signal to slot using new QObject::connect syntax with function pointers?

Tags:

c++

qt

I'm trying to compile this code.

Header:

#ifndef SOCKETTEST_H
#define SOCKETTEST_H

#include <QObject>
#include <QSslSocket>

class SocketTest : public QObject
{
    Q_OBJECT
public:
    explicit SocketTest(QObject *parent = 0);

signals:

public slots:
    void onError(QAbstractSocket::SocketError socketError);

};

#endif // SOCKETTEST_H

Source:

#include "sockettest.h"

SocketTest::SocketTest(QObject *parent) :
    QObject(parent)
{
    QSslSocket *socket = new QSslSocket(this);
    connect(socket, &QSslSocket::error, this, &SocketTest::onError);
}

But I'm getting this error :

sockettest.cpp:7: error: no matching function for call to 'SocketTest::connect(QSslSocket*&, , SocketTest* const, void (SocketTest::*)(QAbstractSocket::SocketError))'

I want to use new syntax of connect() function:

QMetaObject::Connection QObject::connect(const QObject * sender, PointerToMemberFunction signal, const QObject * receiver, PointerToMemberFunction method, Qt::ConnectionType type = Qt::AutoConnection) [static]

So, my question is: How to connect QSslSocket::error() signal to SocketTest::onError() slot using new syntax of connect function?

like image 368
mroot Avatar asked Oct 19 '22 21:10

mroot


1 Answers

Problem: there is another error() in this class. See here, so you should use special trick:

  QObject::connect(socket, static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), [socket] (QAbstractSocket::SocketError) {
        qDebug()<< "ERROR " << socket->errorString();
        socket->deleteLater();
    });
}

Compilable example:

QSslSocket *socket = new QSslSocket(this);
connect(socket, static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error), [socket] (QAbstractSocket::SocketError) {
    qDebug()<< "ERROR " << socket->errorString();
    socket->deleteLater();
});
socket->connectToHostEncrypted("imap.example.com", 993);

I know that this code very ugly but it is only one way to achieve what you want, or of course you can use old syntax.

As doc said:

Overload

As you might see in the example, connecting to QAbstractSocket::error is not really beautiful since error has an overload, and taking the address of an overloaded function requires explicit casting.

Some macro could help (with c++11 or typeof extensions)

The best thing is probably to recommend not to overload signals or slots …

… but we have been adding overloads in past minor releases of Qt because taking the address of a function was not a use case we support. But now this would be impossible without breaking the source compatibility.

like image 132
Kosovan Avatar answered Oct 27 '22 13:10

Kosovan