QSerialPort 读数对于 Qt 小部件刷新得太快
QSerialPort readings refresh too fast for the Qt widget
我正在使用 QSerialPort 从连接到我计算机上的 COM 端口的设备读取数据,它每半秒向我的计算机发送一次字符。我可以从 qDebug window 中读取它们,所以我知道连接正常并且 Qt 接收到数据。
但是我不断地从串行端口读取并刷新我的 GUI 上的标签小部件。 运行 app 标签变成空白,我认为这个问题是标签名称不断刷新引起的。
我的 QserialPort 在主window 构造函数中管理,在析构函数中关闭,并且读取在一个名为 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;
}
您可以随时读取数据,而不仅仅是通过 readyRead
信号。 QSerialPort
class 将缓冲所有接收到的数据,直到您读取它。
您还可以将每个接收到的数据部分附加到一些可滚动的 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
作为其子类)class 不保证一定数量的数据在 readyRead
上可用事件。例如,如果您在另一端一次向端口写入 10 个字节,在某些情况下,您将收到一个信号,该信号允许在所有传输的字节到达之前允许较少的数据可用。
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;
}
我正在使用 QSerialPort 从连接到我计算机上的 COM 端口的设备读取数据,它每半秒向我的计算机发送一次字符。我可以从 qDebug window 中读取它们,所以我知道连接正常并且 Qt 接收到数据。
但是我不断地从串行端口读取并刷新我的 GUI 上的标签小部件。 运行 app 标签变成空白,我认为这个问题是标签名称不断刷新引起的。
我的 QserialPort 在主window 构造函数中管理,在析构函数中关闭,并且读取在一个名为 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;
}
您可以随时读取数据,而不仅仅是通过 readyRead
信号。 QSerialPort
class 将缓冲所有接收到的数据,直到您读取它。
您还可以将每个接收到的数据部分附加到一些可滚动的 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
作为其子类)class 不保证一定数量的数据在 readyRead
上可用事件。例如,如果您在另一端一次向端口写入 10 个字节,在某些情况下,您将收到一个信号,该信号允许在所有传输的字节到达之前允许较少的数据可用。
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;
}