Как заставить QTextBrowser всегда вставлять текст в конце

Я пытаюсь сделать программу последовательного терминала с помощью QTextBrowser для отображения входящих данных с последовательного порта. Я установил QTimer вызывать paintEvent каждые 100 мс и показывать символы на QTextBrowser виджет, если что-либо было получено по последовательному порту.

Моя проблема в том, что каждый раз, когда я нажимаю сказать в середине QTextBrowser, как будто курсор перемещается, а затем на все последующие ui->tbOutput->insertPlainText(QString(buf));только половина QTextBrowser обновляется.

Когда я нажимаю на нижней части QTextBrowser виджет, весь QTextBrowser обновляется снова.

Это код, который у меня есть, где из различных других статей я пытался прокрутить до конца и переместить текстовый курсор до конца, но он не выполняет то, что я хочу.

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

1

Решение

Несколько вещей:

  • QTextBrowser::textCursor возвращает копию, поэтому любые изменения не применяются к документу
  • QTextBrowser::setPosition перемещает курсор в абсолютную позицию, поэтому вы всегда перемещаетесь в позицию 11 (значение int в QTextCursor::End). использование QTextBrowser::movePosition вместо
  • наконец, было бы лучше переместить курсор до добавив текст, так что вы уверены, что он будет добавлен в конце документа.

Вот модифицированный код:

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

С другой стороны, некоторые дополнительные соображения:

  • QIODevice::read(char* data, qint64 maxSize) будет читать максимум maxSize байты, поэтому проверка, является ли количество прочитанных байтов меньше, чем ваш буфер, не требуется.
  • Не делай этого в paintEvent, это не место для чтения данных, а для их отображения. Вместо этого соедините таймер со слотом, прочитайте данные и перекрасьте консоль (ui->tbOutput->update()) только если поступили новые данные.
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]