Qt TextEdit slow - c++

I'd like to have rich text processing for large documents in Qt. The documentation says:
QTextEdit is an advanced WYSIWYG viewer/editor supporting rich text formatting using HTML-style tags, or Markdown format. It is optimized to handle large documents and to respond quickly to user input.
However, both QTextEdit widget and TextEdit QML type seem to be slow. I opened official examples like this one and pasted hundreds of pages of rich text. I also did the same in Microsoft Word. As a result, operations on the text in QTextEdit got really slow while in Microsoft Word it's all fine.
So, is there a way to optimize allegedly optimized TextEdit (widget or QML type) in Qt? Or all the difference is due to Microsoft Wording working on just a visible part of the document while TextEdit is not? To that end, could we reasonably use model/view with QTextEdit?

Related

Multiple visual text cursors in QPlainTextEdit

In Sublime Text, if you hold control while clicking, you can add another cursor to the document, allowing you to type and edit in multiple places at once. I'm trying to recreate this with Qt's QPlainTextEdit. The logic seems pretty simple...
On Ctrl+click, create and store a new cursor at location of the click
Draw all cursors
When any key events happen, make sure the other cursors also receive them
However, it seems that in order to do these things, I have to understand exactly how QPlainTextEdit works, and while I have a loose understanding, I find the source to be very dense and difficult to navigate.
While this feature is very important to me, I can't afford to spend a month on it. I don't know how to reasonably proceed. Is there some open source text editor built with Qt that has this feature? Can I in fact implement it without thoroughly understanding how QPlainTextEdit works? Is there some other solution I have not considered? I thought this would be trivial, or at the very least someone might have solved it before, but that doesn't appear to be the case. Any advice is appreciated.
Is there some open source text editor built with Qt that has this feature?
QtCreator is open-source (source code) and has partial multiple-cursor functionality. While it does not support Ctrl+Click to add a new cursor, you can do Shift+Alt+DownArrow to add a cursor to the following line (same column), like in SublimeText, and then insert text to all the lines at once.
It seems implemented in their class TextEditorWidget, which inherits QPlainTextEdit and reimplements plenty of its virtual methods. I don't exactly know how they implemented the multi-cursor functionality, but probably looking at the code of TextEditorWidget can give hints.
However, keep in mind that QtCreator does not have full multi-cursor functionality like in Sublime Text or CLion: the mutliple cursors are necessarily in the same column, and you cannot move the multiple cursors left/right. For example something I often do in Sublime is multiple selection at the beginning of lines, followed by Ctrl+RightArrow to jump all cursors "one word to the right". You cannot do that in QtCreator as of August 2020.
There is an open feature request for having true multiple-cursor functionality in QtCreator:
https://bugreports.qt.io/browse/QTCREATORBUG-16013
However, it seems that in order to do these things, I have to
understand exactly how QPlainTextEdit works, and while I have a loose
understanding, I find the source to be very dense and difficult to
navigate.
To some extent, but not a lot. Once you get the cursor positions, you know the positions in the document where text needs to be inserted. QTextEdit already supports multiple cursor positions:
https://doc.qt.io/qt-5/richtext-cursor.html
Rich text documents can have multiple cursors associated with them,
and each of these contains information about their position in the
document and any selections that they may hold. This cursor-based
paradigm makes common operations, such as cutting and pasting text,
simple to implement programmatically, yet it also allows more complex
editing operations to be performed on the document.
and
Multiple Cursors
Multiple cursors can be used to simultaneously edit the same document,
although only one will be visible to the user in a QTextEdit widget.
The QTextDocument ensures that each cursor writes text correctly and
does not interfere with any of the others.
Since this feature already exists, it may not be as difficult as thought to read the documentation and implement the feature.
As QPlainTextEdit is implemented by using most of the tech behind QTextEdit and QTextDocument, maybe it will meet your requirements.

How to fast append to QTextEdit

I have an application that has some sort of log viewer, that needs to be able to render formatted log records that are inserted to it in real time.
I am writing this in Qt and so far I was using QTextEdit for rendering of the text, which was beautified using some html tags and later inserted either with setHtml or insertHtml.
The problem is however, that these functions are insanely CPU intensive and run for ages, hanging whole application.
A similar question was asked here: QTextEdit.insertHtml() is very slow
Apart it has no really useful answer, other than stating it's really slow, it actually asks a different thing. I don't need to speed up setHtml or insertHtml. I am willing to use entirely different technique if possible.
Is there any mechanism within Qt that would allow for really fast insertions of text? Or maybe even completely different component than QTextEdit?
Is there any way to append new line to QTextEdit which contains rich text (generated in any way) that is really fast?
I also noticed QTextBrowser but it seems to be just an extension of TextEdit, could it be faster?
You should give QPlainTextEdit a try. It uses the same technology as QTextEdit but is a lot faster. It is optimized for plain text handling but do not let that fool you, it still has some basic support for formatting using HTML. You can append HTML formatted text with appendHtml().
In my application, I also need to display a large log of the task, approximately 3500 lines. Some lines of the log should be colored. For this, I used HTML formatting. QTextEdit.setHtml with this amount of text, freezed my GUI.
I replaced QTextEdit with QListWidget, in which QListWidgetItem is created for each line of the log.
It began to work much faster, without friezes.
And I saved colored text, just simple by using the QListWidgetItem.setForeground.
[This post][1]
[1]: Performantly appending (rich) text to QTextEdit or QTextBrowser in Qt contains an answer to this problem. The gist: instead of simply appending an HTML snippet, manipulate the underlying document directly.
However, I suggest that if your display really is a list of single lines, you create a QAbstractListModel QAbstractTableModel derived class instead and show it in an item view.

Pasting emoji in QT QTextEdit

I'm trying to paste emoji's in the QT QTextEdit box but it's not getting recognized and it's showing as ??? or [][]
I'm not talking about smiley, I'm talking about emoji.
How can I go about making sure that QT's QTextEdit accepts emoji and displays them correctly?
Thank you.
Got it based on the helpful answer below:
SOLUTION:
QFontDatabase fontDB;
fontDB.addApplicationFont(":/Resources/fonts/seguisym.ttf");
QApplication::setFont(QFont(QStringLiteral("Segoe UI Symbol")));
A considerable number of emoji characters are in the Unicode Standard.
If you're, for example, developing with Qt 5.3 in Mac OS X 10.9, pasting emoji characters in text edits should work as it does when pasting any other character.
The reason why your application is showing ?'s and/or []'s is because the current font (perhaps the default system font) doesn't provide representations for emoji "characters".
You can find a proper font out there in the web. Check this for reference.
Then you can add the font to your Qt application
QFontDatabase fontDB;
fontDB.addApplicationFont(":/A Font Supporting Emoji.ttf");
and set it as the font for your application or only your QTextEdit if you prefer
setFont(QFont(QStringLiteral("A Font Supporting Emoji")));
With this your app should be able to display emoji.
The Qt documentation of QTextEdit::paste() says: To change the behavior of this function, i.e. to modify what QTextEdit can paste and how it is being pasted, reimplement the virtual canInsertFromMimeData() and insertFromMimeData() functions.
There you should be able to convert the pasted data e.g. to an HTML img element pointing to a file that is embedded into the application by ressource compiler (or to image file on disk).

QTextEdit vs QPlainTextEdit

What's the difference between QTextEdit and QPlainTextEdit, why use one over the other?
I'm coding a text editor as an exercice to learn Qt5, and now I'm wondering whether to use QTextEdit or QPlainTextEdit.
So far I've only found out that you can display images in QTextEdit, but other than that they look somewhat identical to me.
My text editor should support some basic syntax highlighting (probably using textChanged() signal), but that's pretty much as far as the requirements go.
Google searches for "QTextEdit vs QPlainTextEdit" and "QTextEdit compared to QPlainTextEdit" didn't give me any decent results that would compare the two classes.
From Qt's documentation:
QPlainTextEdit is an advanced viewer/editor supporting plain text. It
is optimized to handle large documents and to respond quickly to user
input.
QPlainText uses very much the same technology and concepts as
QTextEdit, but is optimized for plain text handling.
QPlainTextEdit works on paragraphs and characters. A paragraph is a
formatted string which is word-wrapped to fit into the width of the
widget. By default when reading plain text, one newline signifies a
paragraph. A document consists of zero or more paragraphs. Paragraphs
are separated by hard line breaks. Each character within a paragraph
has its own attributes, for example, font and color.
And later on:
Differences to QTextEdit
QPlainTextEdit is a thin class, implemented by using most of the
technology that is behind QTextEdit and QTextDocument. Its performance
benefits over QTextEdit stem mostly from using a different and
simplified text layout called QPlainTextDocumentLayout on the text
document (see QTextDocument::setDocumentLayout()). The plain text
document layout does not support tables nor embedded frames, and
replaces a pixel-exact height calculation with a line-by-line
respectively paragraph-by-paragraph scrolling approach. This makes it
possible to handle significantly larger documents, and still resize
the editor with line wrap enabled in real time. It also makes for a
fast log viewer (see setMaximumBlockCount()).
So the difference is that QPlainTextEdit is optimized for handling plain text, and can be used even with very large plain text files. Also the way text is formatted is simpler.
If you plan to support only plain texts, then QPlainTextEdit is the right choice.

Populate a QTextDocument from a .odt file

I am writing a rich text editor using C++ and Qt.
For now, I would like it to support (at least) the .odt format.
I found QTextDocumentWriter for writing the contents of the QTextDocument to a file, but I can't seem to find anything to read that back into the QTextDocument, which obviously makes saving it sort of useless in the first place.
So the question is, how do I load an .odt document into a QTextDocument?
Qt does not currently support the ODT format. Okular has code that does parses ODT to a QTextDocument. Beware: Okular source code is released under GPL license.