【问题标题】:QSerialPort readings refresh too fast for the Qt widgetQt 小部件的 QSerialPort 读数刷新太快
【发布时间】:2020-03-25 15:34:51
【问题描述】:

我正在使用 QSerialPort 从连接到我计算机上的 COM 端口的设备读取数据,它每半秒向我的计算机发送一次字符。我可以从 qDebug 窗口中读取它们,所以我知道连接正常并且 Qt 接收到数据。

但是,我不断地从串行端口读取并刷新我的 GUI 上的标签小部件。运行app的时候label变成空白,我认为这个问题是label name不断刷新造成的。

我的 QserialPort 在主窗口构造函数中进行管理,在析构函数中关闭,并且读数是在一个名为 serialReceived() 的函数中完成的,我认为该函数被频繁调用(或导致标签刷新)

    MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    serial = new QSerialPort(this);

    qDebug() << "nb ports: " << QSerialPortInfo::availablePorts().length();
    foreach(const QSerialPortInfo &serialPortInfo, QSerialPortInfo::availablePorts())
    {
qDebug() << "name" << serialPortInfo.portName();
    }

    serial->setPortName("COM11");
    serial->setBaudRate(QSerialPort::Baud9600);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);
    qDebug() << "is " << serial->open(QSerialPort::ReadOnly);
    qDebug() << "err " << serial->error();
    //serial->write("ok");

    // Create the signal and slot
    connect(serial, SIGNAL(readyRead()), this, SLOT(serialReceived()));
}

MainWindow::~MainWindow()
{
    delete ui;
    serial->close(); // instance is closed when mainwindow destroyed
}

void MainWindow::serialReceived()
{
    QByteArray ba;
    ba = serial->readAll();
    ui->label->setText(serial->readAll());
    qDebug()<<ba;
}

【问题讨论】:

    标签: c++ qt serial-port


    【解决方案1】:
    void MainWindow::serialReceived()
    {
        QByteArray ba;
        ba = serial->readAll();
        ui->label->setText(serial->readAll());
        qDebug()<<ba;
    }
    

    您首先将数据读入 ba,然后您尝试再次读取,但由于 readAll() 已经读取了数据,因此什么都没有了。你想要的

    void MainWindow::serialReceived()
    {
        QByteArray ba = serial->readAll();
        ui->label->setText(ba);
        qDebug() << ba;
    }
    

    【讨论】:

      【解决方案2】:

      您可以随时读取数据,而不仅仅是通过readyRead 信号。 QSerialPort 类将缓冲所有接收到的数据,直到您读取它。

      您还可以将收到的每个数据部分附加到一些可滚动的QPlainTextEdit。我推荐这种方式。

      void MainWindow::serialReceived()
      {
          QByteArray ba;
          ba = serial->readAll();
      
          ui->plainTextEdit->appendPlainText(ba);
      }
      

      使用计时器:

      connect(&m_timer, &QTimer::timeout, this, &MyClass::onTimer);
      ...
      m_timer->start(5000);
      ...
      
      void MyClass::onTimer()
      {
          if(serial->bytesAvailable() > 0)
          {
               QByteArray ba;
               ba = serial->readAll();
               ui->label->setText(ba);
               qDebug() << ba;  
          }
      }
      

      您还可以使用QWidget::setUpdatesEnabled() 临时禁用小部件的视觉更新,但似乎您不应该错过部分数据。

      请注意,QIODevice(以及 QSerialPort 也是它的子类)类不保证一定数量的数据将在 readyRead 事件中可用。例如,如果您在另一端一次向端口写入 10 个字节,在某些情况下,您将收到一个信号,即在所有传输的字节到达之前,您会收到允许较少数据可用的信号。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-08
        • 1970-01-01
        • 2014-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-09
        • 2023-04-07
        相关资源
        最近更新 更多