From 0e57a7beef8e7fa530f12fcf6dd3c3f1de9a5094 Mon Sep 17 00:00:00 2001 From: Matt Gajownik Date: Mon, 21 Feb 2022 22:23:52 +1100 Subject: [PATCH] UI: Fix performance issues with the Log Viewer This commit includes two big changes, alongside other smaller tweaks. 1) Update the internal QTextDocument of the text component directly 2) Use QPlainTextEdit, which supports HTML & is designed for long text 3) Use QString's arg function for formatting strings Fix 1 significantly improves realtime performance when adding lines individually, to the point that the UI no longer freezes if the viewer is open and the log is being spammed. It also improves initial launch speed when there's a large amount of text already in the file. Reference: https://stackoverflow.com/a/54501760/2763321 Fix 2 completely eliminates delay when opening the viewer, regardless of how many lines are already in the log file. For a standard log after OBS launch, this cuts opening time from about 2 seconds to half a second. For anything longer than 1,000 lines, the UI no longer freezes, and the viewer (& its contents) open within half a second. Reference: https://stackoverflow.com/a/17466240/2763321 --- UI/log-viewer.cpp | 30 +++++++++++++++++++----------- UI/log-viewer.hpp | 4 ++-- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/UI/log-viewer.cpp b/UI/log-viewer.cpp index 4af26671a..021450069 100644 --- a/UI/log-viewer.cpp +++ b/UI/log-viewer.cpp @@ -24,7 +24,7 @@ OBSLogViewer::OBSLogViewer(QWidget *parent) : QDialog(parent) const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont); - textArea = new QTextEdit(); + textArea = new QPlainTextEdit(); textArea->setReadOnly(true); textArea->setFont(fixedFont); @@ -106,13 +106,21 @@ void OBSLogViewer::InitLog() in.setCodec("UTF-8"); #endif + QTextDocument *doc = textArea->document(); + QTextCursor cursor(doc); + cursor.movePosition(QTextCursor::End); + cursor.beginEditBlock(); while (!in.atEnd()) { QString line = in.readLine(); - AddLine(LOG_INFO, line); + cursor.insertHtml(line); + cursor.insertBlock(); } + cursor.endEditBlock(); file.close(); } + QScrollBar *scroll = textArea->verticalScrollBar(); + scroll->setValue(scroll->maximum()); obsLogViewer = this; } @@ -123,12 +131,10 @@ void OBSLogViewer::AddLine(int type, const QString &str) switch (type) { case LOG_WARNING: - msg = QStringLiteral("") + msg + - QStringLiteral(""); + msg = QString("%1").arg(msg); break; case LOG_ERROR: - msg = QStringLiteral("") + msg + - QStringLiteral(""); + msg = QString("%1").arg(msg); break; } @@ -138,11 +144,13 @@ void OBSLogViewer::AddLine(int type, const QString &str) if (bottomScrolled) scroll->setValue(scroll->maximum()); - QTextCursor newCursor = textArea->textCursor(); - newCursor.movePosition(QTextCursor::End); - newCursor.insertHtml( - QStringLiteral("
") + msg +
-		QStringLiteral("
")); + QTextDocument *doc = textArea->document(); + QTextCursor cursor(doc); + cursor.movePosition(QTextCursor::End); + cursor.beginEditBlock(); + cursor.insertHtml(msg); + cursor.insertBlock(); + cursor.endEditBlock(); if (bottomScrolled) scroll->setValue(scroll->maximum()); diff --git a/UI/log-viewer.hpp b/UI/log-viewer.hpp index 2ca753745..e17a88457 100644 --- a/UI/log-viewer.hpp +++ b/UI/log-viewer.hpp @@ -1,13 +1,13 @@ #pragma once #include -#include +#include #include "obs-app.hpp" class OBSLogViewer : public QDialog { Q_OBJECT - QPointer textArea; + QPointer textArea; void InitLog();