我正在尝试使用QTextBrowser
来显示来自串行端口的传入数据的串行终端程序。我已设置QTimer
每100毫秒调用一次paintEvent,并在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);
}
}
}
答案 0 :(得分: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()
)。