Solved How to write data to TcpSocket from another thread?
-
Hi
Could you not just use signal and slot ?
So when UART has data it emit signal to MyServer to actually send some reply ?
But im having hard time to understand the code as you seem to both
make a UART_Protokol and Myserver in main but at the same time
also make new one in void MyServer::read() and
a server in void UART_Protokol::ParseCommand()
so im not really sure what class should be talking to what class. -
I've tried using the signal for the recording method but nothing either fail.
It was necessary to create a new class to inherit Q_OBJECT otherwise the linker does not allow to use WiringPi for work with UART.
class Signals: public QObject { Q_OBJECT public: Signals(); public slots: void setValue(); signals: void event_uart(); };
Signals::Signals(){} void Signals::setValue() { emit event_uart(); }
The MyServer::write slot does not work when sending a signal.
void MyServer::incomingConnection(int socketDescriptor ) { socket = new QTcpSocket(this); Signals ref; socket->setSocketDescriptor( socketDescriptor ); connect(socket,SIGNAL(readyRead()),this,SLOT(read())); connect(socket,SIGNAL(disconnected()),this,SLOT(disconect())); connect(&ref,SIGNAL(event_uart()), this,SLOT(write())); //connected signal with UART qDebug()<<socketDescriptor<<"Client connected"; socket->write("Connection"); }
void UART_Protokol::ParseCommand() { Signals ref; if(sp_dataString == "Start") { TransmitData = "ready"; sp_Send(TransmitData); qDebug()<<"Self-test"; } if(sp_dataString == "ready") qDebug()<<"Self-test"; if (sp_dataString =="MG1") { qDebug()<<"Start calibration..."; ref.setValue(); // send signal } if (sp_dataString =="MG0") { qDebug()<<"End calibration..."; ref.setValue(); } if (sp_dataString =="MG") { qDebug()<<"Calibration..."; } }
-
Hi
I wonder aboutvoid MyServer::incomingConnection(int socketDescriptor ) { socket = new QTcpSocket(this); Signals ref; // this is local object and will be deleted as soon as function ends socket->setSocketDescriptor( socketDescriptor ); connect(socket,SIGNAL(readyRead()),this,SLOT(read())); connect(socket,SIGNAL(disconnected()),this,SLOT(disconect())); connect(&ref,SIGNAL(event_uart()), this,SLOT(write())); //connected signal with UART qDebug()<<socketDescriptor<<"Client connected"; socket->write("Connection"); }
Since Signals ref; is gone as soon as function ends, how will it ever emit event_uart()
once data arrives ?i was expecting something like
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); UART_Protokol Serial; Serial.StartProtokol( false ); std::thread serial (&UART_Protokol::Event, Serial); MyServer Server; connect(&Serial, UART_Protokol::ServerWrite, &Server, MyServer::write, Qt::QueuedConnection); // or similar Server.startserver(); return a.exec(); } and then in (and other places ) void UART_Protokol::ParseCommand() { // MyServer myserver; // why make a new local server when you have one in main ?? ..... if (sp_dataString =="MG1") emit ServerWrite("MG1"); //emit signal to server in main ..... }
-
I can't use the emit ServerWrite signal because I need UART_Protokol class inherit to the QObject class without this will be error when creating the signal slot. But i cannot inherit this class because the linker throws an error.
class UART_Protokol { Q_OBJECT //If i inherit QObject to the UART_Protokol: undefined reference to `vtable for UART_Protokol' //And without Q_OBJECT I can't use signals signals: void ServerWrite (QByteArray dat);
Is this how it's gonna work? Can I use a signal from another class?
QObject::connect (&signal,&Signals::setValue, &Server,&MyServer::write, Qt::QueuedConnection);
-
HI
Cant you just do
class UART_Protokol : public QObject
{
Q_OBJECT
...ah,
undefined reference to `vtable for UART_Protokol'thats happens often.
just inherit from QObject
then clean all of build folder
and then rebuild all.
Its a known error coming from not all is recompiled after adding QObject -
I cleaned up the entire contents of the folder and reassembled everything. Error appeared: "Class contains Q_OBJECT macro but does not inherit from QObject ":
/#ifndef PROTOKOL_OBMENA_CHEREZ_UART_H #define PROTOKOL_OBMENA_CHEREZ_UART_H #include <QString> #include <thread> #include <myserver.h> #include <QObject> class UART_Protokol { Q_OBJECT
If inherit a class from QObject how in other example, other errors occur:
#ifndef PROTOKOL_OBMENA_CHEREZ_UART_H #define PROTOKOL_OBMENA_CHEREZ_UART_H #include <QString> #include <thread> #include <myserver.h> #include <QObject> class UART_Protokol : public QObject { Q_OBJECT
use of deleted function ‘UART_Protokol::UART_Protokol(const UART_Protokol&)’
: _M_head_impl(std::forward<_UHead>(__h)) { }‘QObject::QObject(const QObject&)’ is private within this context
use of deleted function ‘QObject::QObject(const QObject&)’
class UART_Protokol : public QObject
^~~~~~~~~~~~~
^
no matching function for call to ‘std::tuple<std::_Mem_fn<void (UART_Protokol::)()>, UART_Protokol>::tuple(std::_Mem_fn<void (UART_Protokol::)()>, UART_Protokol&)’
: _M_bound(std::forward<_Tp>(__f), std::forward<_Up>(__args)...)
^ -
Hi,
That means that you are trying to copy an instance of your object which is not possible with QObject based classes.
See here for more information.
-
If I inherit the class :
class UART_Protokol : public QObject { Q_OBJECT
and comment on a thread, everything is going without errors:
// std::thread serial (&UART_Protokol::Event, Serial); // serial.detach();
even connecting signal to slot, build is fine:
QObject::connect (&Serial,&UART_Protokol::ServerWrite, &Server,&MyServer::write, Qt::QueuedConnection);
That's just it I need to check the UART buffer for reading messages.
-
Did you read the document I linked regarding copying QObject based classes ?
-
Thank you all for your help, the signals really work fine and now i can easily pass the calibration data of the magnetometer! The truth is everything works in one thread with a timer but the delay is not big.