【问题标题】:QSerialPort in while Loop?QSerialPort 在 while 循环中?
【发布时间】:2023-03-21 01:00:01
【问题描述】:

我有一个通过 RS-232 向超级终端发送数据的功能。该函数在 while 循环之外正常工作,但是,在 while 循环中,它仅在第一次发送之后它不发送任何内容。

    qDebug() << MESSAGE;
    int choice;
    std::cin >> choice;

    while( choice != 3 )
    {
        switch (choice)
        {
            case 1:
                // Ready to send data 
                port->write("QSerial Port!\r\n");
                break;
            case 2:
                qDebug() << "Todo...";
                break;
            case 3:
                break;
            default:
                qDebug() << "Invalid Choice ...";
        }
        qDebug() << MESSAGE;
        std::cin >> choice;
    }

编辑:

#include <QCoreApplication>
#include <iostream>
#include <QDebug>
#include <QSerialPort>

const char MESSAGE[] = "\n----- New Menu ----"
                       "\n1- Send Data     \n"
                       "2- Receive Data    \n"
                       "3- Quit:           \n";


int main(int argc, char *argv[])
{
    QCoreApplication  app(argc, argv);

    QSerialPort *port = new QSerialPort;
    port->setPortName("COM4");


    // Check the validity of the port
    if ( !port->open(QIODevice::ReadWrite) )
    {
        qDebug() << "\nError: " << port->portName() << " port can't be opened ...";
        return -1;
    }else{
        qDebug() << '\n' << port->portName() << " port has been opened successfully ...";
        port->setBaudRate(QSerialPort::Baud9600);
        port->setStopBits(QSerialPort::OneStop);
        port->setDataBits(QSerialPort::Data8);
        port->setParity(QSerialPort::NoParity);
        port->setFlowControl(QSerialPort::NoFlowControl);
        qDebug() << port->portName() << " port has been configured correctly ...";
    }

    qDebug() << MESSAGE;
    int choice;
    std::cin >> choice;

    while( choice != 3 )
    {
        switch (choice)
        {
            case 1:
            {
                // Ready to send data 
                if ( port->write("QSerial Port!\r\n", qstrlen("QSerial Port!\r\n")) == -1)
                {
                    qDebug() << port->errorString();
                }
                //port->bytesWritten(strlen("QSerial Port!\r\n"));
                port->waitForBytesWritten(-1);
                //qDebug() << port->errorString();
            }
                break;
            case 2:
                qDebug() << "Todo...";
                break;
            case 3:
                break;
            default:
                qDebug() << "Invalid Choice ...";
        }
        qDebug() << MESSAGE;
        std::cin >> choice;
    }

    qDebug() << "\n Goodbye ....";
    port->close();
    delete port;
    return app.exec();
}

【问题讨论】:

  • 请显示port-&gt;errorString()的输出。另外,请说明如何配置 qtserialport 对象,如何打开它。您使用的是 QtSerialPort 5.2.1,对吗?
  • if ( port-&gt;write("QSerial Port!\r\n", qstrlen("QSerial Port!\r\n")) == -1) { qDebug() &lt;&lt; port-&gt;errorString(); }
  • 这是我检查错误的功能,但我什么也没得到。我不认为有错误,但是,我猜你说的是对的,那就是发送下一个数据的等待时间问题。
  • 这是哪个操作系统?它是 32 位还是 64 位?是 QtSerialPort 5.2.1 还是 Qt 4? USB 串口还是原生?
  • 64 位 Windows,QtSerialPort 5.2.1。虚拟串口驱动

标签: c++ qt qt5 qtcore qtserialport


【解决方案1】:

您的代码存在以下缺陷:

1) 你不处理错误。

2) 你没有检查写操作的返回值。

3) 在再次写入之前,您似乎没有以编程方式等待。这是不正确的。使用同步 waitForBytesWritten 或异步 bytesWritten 信号为下一次写入提供绿灯。

最关键的可能是最后一点。这将导致如何发送数据的“随机”行为。在这种特殊情况下,它可能会按顺序发送,因为等待输入可能会花费您更长的时间,但编写的代码仍然不稳定且健壮。

【讨论】:

  • 我认为您提到的最后一点是正确的。如果我使用port-&gt;waitForBytesWritten(-1);,它完全符合我的要求,但是它的行为很奇怪。比如第一次发送QSerial Port!\r\n一次。我第二次发送它,消息加倍。第三次消息是三倍,依此类推。
  • @CroCo:显示重现问题的整个代码。
【解决方案2】:

我不能完全同意第 (3) 点。 没有什么可以说你不能写第二个,而第一个仍然很出色。原则上,数据应该只是添加到传输队列中。 这就像说“在先前的数据写入磁盘之前,您不能再次写入此文件”。 我在做 qtserial 时遇到了类似的问题:

while (..)
{
    <send data>
    <receive data>
}

原来你必须先做一个 qApp->processEvents() 才能收到任何东西 或在您写入新数据之前。 我期待与读取/写入文件相同的行为。 对我来说,qtserial 的行为与您期望的设备不同。

【讨论】:

  • 你是对的。使用qApp-&gt;processEvent() 后,它的行为符合我的预期。奇怪的是,在文档中没有关于将 qApp->processEvents() 用于 QSerialPort 类的内容。
  • @CroCo:fwiw,我是 QtSerialPort 和 Sergey 的贡献者之一,从我能说的角度来看,这个答案并不正确。不需要显式处理事件。即使它看起来有效,也不是正确的方法。我仍然坚持我说的是真的。图书馆就是这样设计的。一般来说,你可以连续写,但在这种情况下,我以为你会在另一边分块处理消息?
  • @LaszloPapp,再次感谢您的建议。您能否提供一个简单的示例,以便我进行测试。从理论上讲,格特所说的是正确的,但我仍然对 QSerialPort 类感到困惑。我已经看到很多人抱怨 Qt 中的 while 循环。关于这个问题,至少对于初学者来说是隐藏的。
猜你喜欢
  • 2015-10-21
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-02
  • 2011-08-09
  • 2021-07-18
相关资源
最近更新 更多