Home > OS >  Qt6 Connect Signal to Lambda Function
Qt6 Connect Signal to Lambda Function

Time:12-02

I'm using a DataRouter class to handle communication with a QSerialPort (and then communicate the results elsewhere). The connected device sends a status package every second or so, and I would like to read it without polling the device. I tried directly using QSerialPort's waitForReadyRead function, but no matter how long I set the wait time, it always timed out. Looking here and here I saw signals can be connected to Lambda functions. Now I'm trying to connect QSerialPort's readyRead signal to a Lambda which calls my on_dataRecieved function but I get the error C2665:"QObject::connect: none of the 3 overloads could convert all of the argument types. Below is an example of what I have:

DataRouter.h

template<class SerialPort>
class DataRouter
{
public:
    DataRouter ();
private slots:
    on_dataRecieved();
private:
    shared_ptr<SerialPort> m_port;
};

DataRouter.cpp

template<class SerialPort>
DataRouter<SerialPort>::DataRouter()
{
    m_port = std::make_shared<SerialPort>()
    QObject::connect(m_port, &QSerialPort::readyRead, this, [=](){this->on_dataRecieved();})
}

template<class SerialPort>
void DataRouter<SerialPort>::on_dataRecieved()
{
 //Do stuff
}

CodePudding user response:

If your "target" is not QObject you need to use the following overload of connect. The problem is that, you are trying to use non-QObject as "context" to determine the lifetime of the connection and that's not possible. To mitigate it you will need to release the connection somehow on DataRouter's destruction; one way is to store what connect() will have returned and call disconnect on it later on.

As for the signal coming from a smart pointer, have you tried this: connect(m_port->get(), &QSerialPort::readyRead, &DataRouter::on_dataRecieved);

CodePudding user response:

Your m_port is not entity of QSerialPort class, that's why you don't have QSerialPort::readyRead that can be emitted from it. template<class SerialPort> doesn't do what you what, it is just name of templated parameter. You probably wanted something like this:

DataRouter.h

class DataRouter : QObject
{
public:
    DataRouter ();
private slots:
    on_dataRecieved();
private:
    QSerialPort* m_port;
};

DataRouter.cpp

DataRouter::DataRouter()
{
    m_port = new QSerialPort(this);
    connect(m_port, &QSerialPort::readyRead, this, &DataRouter::on_dataRecieved);
    // or connect(m_port, &QSerialPort::readyRead, this, [this](){this->on_dataRecieved();});
}

void DataRouter::on_dataRecieved()
{
 //Do stuff
}

You don't have to wrap Qt classes in smart pointers as long, as you provide parent class for them. Memory freed when parent is destructed.

  • Related