如何在其他类的嵌套循环中获得主事件循环QCoreApplication,以实现网络操作
How to get to the main event loop QCoreApplication within nested loops of other classes for implementing networking operations?
这篇文章类似于我发布的第一个,但我做了一些改变,我知道什么是错的。错误位于事件循环QCoreApplication中,该循环未在嵌套循环中调用,因此无法满足网络事件。我的问题总是发送json到我的API Rest。这是我的代码:主类从串行端口调用SerialReader的字节定律,确定包是否正确,如果它发送解析器类划分各种字节,然后发送那些所需的API
这是我的main.cppint main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
SerialReader serialReader;
QTimer::singleShot(0, &serialReader, SLOT(runSerialReader()));
...
return a.exec();
}
这是我的serialreader.cpp/serialreader.h
/*serialreader.h*/
class SerialReader : public QObject
{
Q_OBJECT
...
public:
void processData(QByteArray datas);
public slots:
void runSerialReader();
private:
Parser parser;
...
};
/*serialreader.cpp*/
SerialReader::SerialReader() {}
void SerialReader::runSerialReader(){
...
if (serialPort->isOpen())
{
qDebug() << "Serial port is open...";
while (serialPort->waitForReadyRead(50))
{
QByteArray datas = serialPort->readAll();
if (datas.size() == 0){
qDebug() << "ERROR data not read";
} else {
processData(datas);
}
}
} else {
qDebug() << "OPEN ERROR: " << serialPort->errorString();
}
serialPort->close();
qDebug() << "...serial port is closed!";
...
}
void SerialReader::processData(QByteArray datas)
{
for (int i = 0; i < datas.size(); i++)
{
switch (state)
{
...
case EXIT:
...
parser.setPackage(serialBuffer);
...
}
}
}
这是我的解析器。cpp/parser.h
/*parser.h*/
class Parser : public QObject
{
Q_OBJECT
public:
...
QQueue<QByteArray> queue;
void setPackage(QByteArray &serialBuffer);
void sendPacketToAPI(QByteArray &bufferToPacket);
public slots:
void replyFinished(QNetworkReply *reply);
private:
QNetworkAccessManager *m_manager;
quint8 m_a;
quint8 m_b;
}
/*parser.cpp*/
Parser::Parser()
: m_manager { new QNetworkAccessManager }
{
connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
void Parser::setPackage(QByteArray &serialBuffer){
...
bufferToPacket.append(bufferToParse.at(i));
...
}
void Parser::replyFinished(QNetworkReply *reply)
{
reply->deleteLater();
qDebug() << "~error " << reply->errorString();
qDebug() << "reply delete!";
qDebug() << "https post_request done!";
}
void Parser::sendPacketToAPI(QByteArray &bufferToPacket){
m_a = bufferToPacket.at(0);
m_b = bufferToPacket.at(1);
QNetworkRequest request;
request.setUrl(QUrl ("http://..."));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QString json = QString("{"a":"%1","b":"%2"}").arg(m_a).arg(m_b);
m_manager->post(request, json.toUtf8());
QCoreApplication :: processEvents (QEventLoop :: AllEvents);
}
在实际操作中,在进入串行读卡器后连续读取字节,从而形成一个无限循环,因此总是会召回所有嵌套的方法。我试图用静态方法QCoreApplication::processEvents(QEventLoop::AllEvents)
解决问题,但我无法播放主循环QCoreApplication。我该怎么办?
调用QCoreApplication::processEvents似乎不是一个好的解决方案,并且您不需要进行少量重构。Qt提供了两个选项来处理串行端口。您可以使用QSerialPort的阻塞API或异步API。然而,当使用阻塞API时(正如您在调用waitForReadyRead()时所做的那样),您应该将读取串行数据的代码移动到一些工作线程中,以避免阻塞主事件循环。另一个选择是使用async API并连接到readyRead()信号来处理传入的数据。
在您的情况下,可能更容易做的是修改SerialReader类,并将while(…)循环替换为连接到readyRead()信号的插槽中的传入数据的异步处理。
QSerialPort有很好的例子http://doc.qt.io/qt-5/qtserialport-examples.html
- 没有找到相关文章