c++qtqtextbrowserqtextcursor

How to get QTextBrowser to always insert text at the end


I am trying to make a serial terminal program by using QTextBrowser to display incoming data from a serial port. I have set a QTimer to call the paintEvent every 100ms, and show characters on the QTextBrowser widget if anything was received on the serial port.

My problem is that every time I click say in the middle of the QTextBrowser, it is as if though the cursor moves and then on all subsequent ui->tbOutput->insertPlainText(QString(buf));, only half of the QTextBrowser gets updated.

When I click on the bottom of the QTextBrowser widget, the whole QTextBrowser is updated again.

This is the code that I have, where from various other articles, I have tried to scroll to the bottom, and move the text cursor to the end, but it does not do what I want.

void MainWindow::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    static char buf[10240];

    if (terminal->serialport.bytesAvailable() > 0)
    {
        // sizeof(buf)-1 so that there is space for zero termination character
        qint64 numread = terminal->serialport.read(buf,sizeof(buf)-1); 

        if ((numread > 0) && (numread < sizeof(buf)))
        {
            buf[numread] = 0; // set zero termination
            ui->tbOutput->insertPlainText(QString(buf));
            ui->tbOutput->verticalScrollBar()->setValue(
                ui->tbOutput->verticalScrollBar()->maximum());

            ui->tbOutput->textCursor().setPosition(QTextCursor::End);
        }
    }
}

Solution

  • A few things:

    Here the modified code:

    void MainWindow::paintEvent(QPaintEvent *event)
    {
        Q_UNUSED(event);
    
        static char buf[10240];
    
        if (terminal->serialport.bytesAvailable() > 0)
        {
            // sizeof(buf)-1 so that there is space for zero termination character
            qint64 numread = terminal->serialport.read(buf,sizeof(buf)-1); 
    
            if ((numread > 0) && (numread < sizeof(buf)))
            {
                buf[numread] = 0; // set zero termination
                auto textCursor = ui->tbOutput->textCursor();
                textCursor.movePosition(QTextCursor::End);
                ui->tbOutput->setTextCursor(textCursor);
                ui->tbOutput->insertPlainText(QString(buf));
                ui->tbOutput->verticalScrollBar()->setValue(
                    ui->tbOutput->verticalScrollBar()->maximum());
            }
        }
    }
    

    On the other hand, some additional considerations: