Simple stripchart in C++ / Qt

1.7k views Asked by At

I have some data coming over serial connection into my C++ Application. Now I wan't to make a simple GUI with a strip chart of those data plus some buttons. (Something like 10Hz refresh rate)

The Buttons are not really a problem. But I didn't find any Qt plugin for strip charts. Is there any or some other library I could call from c++. There should be plenty considering that it is rather simple and common task.

OS: Ubuntu

CC: g++

2

There are 2 answers

0
Marco A. On BEST ANSWER
2
László Papp On

This does not necessarily need a separate library on its own, but it is common to combine such QtSerialPort and Qwt for such use cases.

The basic principle is to use asynchronous reading. You could run a timer internally with a fixed period, and then you could draw the next part of the "strip chart" in each interval that you specify.

You could do this until a certain condition is met, like there is no more data available and so forth. You have not mentioned whether you are using QtSerialPort, but this is almost tangential even though it would probably make sense to use it in a Qt Project.

You could write something like the code below in QtSerialPort for our async reader example. The idea is that you append periodically into your graphical widget.

SerialPortReader::SerialPortReader(QSerialPort *serialPort, QObject *parent)
    : QObject(parent)
    , m_serialPort(serialPort)
    , m_standardOutput(stdout)
{
    connect(m_serialPort, SIGNAL(readyRead()), SLOT(handleReadyRead()));
    connect(m_serialPort, SIGNAL(error(QSerialPort::SerialPortError)), SLOT(handleError(QSerialPort::SerialPortError)));
    connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));

    m_timer.start(5000);
}

SerialPortReader::~SerialPortReader()
{
}

void SerialPortReader::handleReadyRead()
{
    m_readData.append(m_serialPort->readAll());
    // *** This will display the next part of the strip chart ***
    // *** Optionally make the use of a plotting library here as 'Qwt' ***
    myWidget.append('=');

    if (!m_timer.isActive())
        m_timer.start(5000);
}

void SerialPortReader::handleTimeout()
{
    if (m_readData.isEmpty()) {
        m_standardOutput << QObject::tr("No data was currently available for reading from port %1").arg(m_serialPort->portName()) << endl;
    } else {
        m_standardOutput << QObject::tr("Data successfully received from port %1").arg(m_serialPort->portName()) << endl;
        m_standardOutput << m_readData << endl;
    }

    QCoreApplication::quit();
}

void SerialPortReader::handleError(QSerialPort::SerialPortError serialPortError)
{
    if (serialPortError == QSerialPort::ReadError) {
        m_standardOutput << QObject::tr("An I/O error occurred while reading the data from port %1, error: %2").arg(m_serialPort->portName()).arg(m_serialPort->errorString()) << endl;
        QCoreApplication::exit(1);
    }
}