Używam QSerialport, aby odczytać z urządzenia podłączonego do portu COM na moim komputerze i wysyła znaki co pół sekundy do mojego komputera. Mogę je przeczytać z okna QDebug, więc znam prace związane z połączeniem i QT otrzymują dane.
Jednak stale czytam z portu szeregowego i odświeżam widżet etykiety na moim GUI. Etykieta staje się pusta, gdy uruchomię aplikację, myślę, że ten problem jest spowodowany przez nazwę etykiety stale odświeżającą.
Mój QSerialport jest zarządzany w konstruktorze Mainwindow, zamknięte w destructor, a odczyty są wykonywane w funkcji zwanej serialReceived (), co wierzę, że nazywa się zbyt często (lub powoduje, że etykieta)
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 odpowiedzi
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->label->setText(serial->readAll());
qDebug()<<ba;
}
Najpierw czytasz dane do ba, a następnie próbujesz ponownie przeczytać, ale ponieważ Readall () już przeczytaj dane, nie ma nic. Chcesz
void MainWindow::serialReceived()
{
QByteArray ba = serial->readAll();
ui->label->setText(ba);
qDebug() << ba;
}
Wystarczy odczytać dane w dowolnym momencie, nie tylko przez sygnał readyRead
. Klasa QSerialPort
będzie buforować wszystkie otrzymane dane, dopóki go przeczytasz.
Możesz także dołączyć każdą otrzymaną część danych do jakiejś przewijania QPlainTextEdit
. Polecam w ten sposób.
void MainWindow::serialReceived()
{
QByteArray ba;
ba = serial->readAll();
ui->plainTextEdit->appendPlainText(ba);
}
Korzystanie z timera:
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;
}
}
Możesz także tymczasowe wyłączone aktualizacje wizualne widget za pomocą QWidget :: SetUpdatesenabled ( ), ale wydaje się, że nie powinieneś przegapić części danych.
Uwaga, QIODevice
(i QSerialPort
jako jego Subass, również) Klasa nie gwarantuje, że pewna ilość danych będzie dostępna na zdarzeniu {x2}}. Na przykład, jeśli napisałeś 10 bajtów do portu na raz na drugim końcu, w niektórych przypadkach otrzymasz sygnał, który umożliwi mniej danych będzie dostępny w Monencie, czyli przede wszystkim przenoszone bajty.
Podobne pytania
Nowe pytania
c++
C ++ to język programowania ogólnego przeznaczenia. Pierwotnie został zaprojektowany jako rozszerzenie C i ma podobną składnię, ale teraz jest to zupełnie inny język. Użyj tego tagu w przypadku pytań dotyczących kodu (który ma zostać) skompilowany za pomocą kompilatora C ++. Użyj znacznika specyficznego dla wersji w przypadku pytań związanych z określoną wersją standardu [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] lub [C ++ 23] itp. .