Показания QSerialPort refre sh слишком быстрые для виджета Qt - PullRequest
0 голосов
/ 25 марта 2020

Я использую QSerialPort для чтения с устройства, подключенного к COM-порту на моем компьютере, и каждые полсекунды он отправляет символы на мой компьютер. Я могу прочитать их из окна qDebug, так что я знаю, что соединение работает, и Qt получает данные.

Однако я постоянно читаю из последовательного порта и пересылаю sh виджет метки на моем GUI. Метка становится пустой, когда я запускаю приложение, я думаю, что эта проблема вызвана тем, что имя метки постоянно обновляется.

Мой QserialPort управляется в конструкторе mainwindow, закрывается в деструкторе, а чтения выполняются в функции named serialReceived (), который, как мне кажется, вызывается (или заставляет метку переопределять sh) слишком часто

    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;
}

Ответы [ 2 ]

1 голос
/ 25 марта 2020
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;
}
1 голос
/ 25 марта 2020

Вы можете читать данные в любое время, не только по сигналу 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 () , но, похоже, вам не следует пропускать часть данных.

Обратите внимание, что класс QIODeviceQSerialPort также как его подкласс) не гарантирует, что определенный объем данных будет доступен в readyRead событие. Например, если вы записали 10 байтов в порт за раз на другом конце, в некоторых случаях вы получите сигнал, который позволит меньшему количеству данных быть доступными в моненте, то есть до того, как все переданные байты поступят.

...