Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QTextEdit change font of individual paragraph/block

Tags:

c++

qt

qtextedit

Using a QTextEdit, I need to change the font attributes of each paragraph individually. This is similar to how many word processors change the font of a paragraph when the user select a style from a menu (not a specific formatting).

Ideally, I would like to apply a QTextCharFormat (or equivalent) to a block (paragraph) just before it is laid out and rendered, but I would prefer that no font attribute be actually inserted in the text, as I don't want this information in the file but I need to preserve any bold/italic/underline attributes that the user might have set to words within paragraphs (I intend to save the needed information in a QTextBlock::userData). However, I can't figure where I would need to insert a function to perform this task.

I figured I could not change the QTextCharFormat of a paragraph from either QTextBlock nor QTextCursor as this only applies to new blocks, it doesn't affect blocks with existing text.

I checked out QTextLayout but I don't think my answer is there.

I have been looking for a solution to this problem for a few days now. I would be really gracious for any pointer in the right direction.

I have years of experience with C++, but I'm somewhat new to Qt. Using Qt 4.8.

Edit:

I added emphasize (bold) above to an important part of what I'm trying to do. In other word, what I'd really like to do is be able to apply the font attributes to the block of text (perhaps a temporary copy) just before it is displayed. I'm totally comfortable with deriving and modifying (even reimplement) any class that I need to in order to achieve that goal, but I need to be pointed to the right direction as to what I actually need to change. As a last resort, I could also modify some Qt class directly if that is necessary for the task, but again would need to know what class I need to touch. I hope this is clearer. I find it difficult to explain this without being allowed to tell you what the application will do exactly.

like image 732
Tom Duhamel Avatar asked Dec 31 '14 05:12

Tom Duhamel


People also ask

What are the attributes of a paragraph in qtextedit?

Each character within a paragraph has its own attributes, for example, font and color. QTextEdit can display images, lists and tables. If the text is too large to view within the text edit’s viewport, scroll bars will appear.

Does setfont work on qplaintextedit?

(BTW, setFont works fine on QPlainTextEdit, it does not have to be on QTextDocument.) This is strange to me that one has to specify a bogus font name to get it resolved. If I use QFont's default constructor, or anything else I tried, it does not change the font to be monospaced. I wish there would be a more elegant solution.

How do I limit the number of paragraphs in a qtextedit?

If you want to limit the total number of paragraphs in a QTextEdit , as for example it is often useful in a log viewer, then you can use QTextDocument ‘s maximumBlockCount property for that. When QTextEdit is used read-only the key bindings are limited to navigation, and text may only be selected with the mouse: Moves one line up.

What is textchanged in qtextedit?

The textChanged () signal is emitted whenever the text changes (as a result of setText () or through the editor itself). QTextEdit holds a QTextDocument object which can be retrieved using the document () method. You can also set your own document object using setDocument () .


1 Answers

[Required Libraries]

#include <QTextEdit>    // not needed if using the designer

#include <QTextDocument>
#include <QTextBlock>
#include <QTextCursor>

[Strategy]

QTextDocument

I need it to manage the blocks. The function QTextDocument::findBlockByNumber is quite handy to locate the previous blocks, and I think it is what you are after.

QTextBlock

Container for block texts. A nice and handy class.

QTextCursor

Surprisingly, there is no format-setter in QTextBlock class. Therefore I use QTextCursor as a workaround since there are four format-setters in this class.

[Code for formatting]

// For block management
QTextDocument *doc = new QTextDocument(this);
ui->textEdit->setDocument(doc);  // from QTextEdit created by the Designer
//-------------------------------------------------
// Locate the 1st block
QTextBlock block = doc->findBlockByNumber(0);

// Initiate a copy of cursor on the block
// Notice: it won't change any cursor behavior of the text editor, since it 
//         just another copy of cursor, and it's "invisible" from the editor.
QTextCursor cursor(block);

// Set background color
QTextBlockFormat blockFormat = cursor.blockFormat();
blockFormat.setBackground(QColor(Qt::yellow));
cursor.setBlockFormat(blockFormat);

// Set font
for (QTextBlock::iterator it = cursor.block().begin(); !(it.atEnd()); ++it)
{
    QTextCharFormat charFormat = it.fragment().charFormat();
    charFormat.setFont(QFont("Times", 15, QFont::Bold));

    QTextCursor tempCursor = cursor;
    tempCursor.setPosition(it.fragment().position());
    tempCursor.setPosition(it.fragment().position() + it.fragment().length(), QTextCursor::KeepAnchor);
    tempCursor.setCharFormat(charFormat);
}

Reference: How to change current line format in QTextEdit without selection?


[DEMO]

Building Environment: Qt 4.8 + MSVC2010 compiler + Windows 7 32 bit

The demo is just for showing the concept of setting the format on a specific block.

Plain text input

enter image description here

Format 1 (notice that it won't bother the current cursor in view)

enter image description here

Format 2

enter image description here

like image 79
Tay2510 Avatar answered Sep 18 '22 00:09

Tay2510