QEventLoop wait for a signal
-
Hi guys!
I'am currently work with a project that was used with QEventloop, please take a glance to the following code:TestTcp.h
class TCPOperation: public QObject { enum struct SlotOperations { Connect, Disconnect }; Q_OBJECT public: TCPCommander(QString id); ~TCPCommander(); bool init(QString ip, int port); public slots: bool testOp(QString); private: template<SlotOperations> void SignalAndSlot(); private slots: void readData(); bool waitCmd(int index, int timeout); signals: void ackRight(); private: using Equal_t=std::integral_constant<int,0>; QString zid; QScopedPointer<QTcpSocket,QPUNDetails::TcpSocketQPDeleter> tcpClient{nullptr}; int cmdTimeout = 10000; bool cmdError = false; };
TestTcp.cpp
#include "TestTcp.h" TCPOperation::TCPOperation(QString id) { zid = id; connect(tcpClient.data(), SIGNAL(readyRead()), this, SLOT(readData())); } TCPOperation::~TCPOperation() { } void TCPOperation::readData() { while (tcpClient->bytesAvailable() > 0) { QByteArray datagram; datagram.resize(tcpClient->bytesAvailable()); tcpClient->read(datagram.data(), datagram.size()); if(xxxx) { emit ackright(); } } } bool TCPOperation::testStart(QString panelid) { if (bConnected) { int ret = tcpClient->write(panelid.toLatin1()); tcpClient->flush(); if (-1 == ret) return false; return waitCmd(cmdIndex, cmdTimeout); } return false; } bool TCPOperation::waitCmd(int index, int timeout) { QEventLoop loop; QTimer cmdTimer; cmdError = false; cmdTimer.setSingleShot(true); cmdTimer.setTimerType(Qt::PreciseTimer); connect(&cmdTimer, SIGNAL(timeout()), &loop, SLOT(quit()), Qt::UniqueConnection); connect(this, SIGNAL(ackRight()), &loop, SLOT(quit()), Qt::UniqueConnection); cmdTimer.start(timeout); loop.exec(); if (cmdTimer.isActive() && index == cmdIndex) { cmdTimer.stop(); cmdTimer.deleteLater(); if (!cmdError) return true; else return false; } else { cmdTimer.stop(); return false; } }
As you saiad , the above code is minimal demo to reproduce my problem. The purpose of the waitcmd is that I want the function test is blocked until the signal ackright() is emitted from function readData(). The function readData() is called when the signal readready of QTcpSocket was emitted. it's executed well in most time. However, Sometimes the slots function readData cannot be will called when the signal readready from QTcpSocket, it will only be called when the QEventLoop get a timeout.
additional, the function teststart may be called in a instance of qthread.
Can someone give me a anwser to this problem , thanks bro!
-
Hi,
Since there's no information about the conditions, I would say that you are not cumulating the data your receive correctly.
-
In other words, are there some potential reasons will generate a risk to my problem, bro.
-
The issue is that you are handling the incoming data as if you would get full frames every time you receive something. There's no guarantee for that. Hence you should fix your buffer usage. Cumulate all the data until you know you have a full frame ready to be parsed further.