QTextCursor and CSS: Problem with text-indent property
-
I'm building a QTextDocument using QTextCursor and setHtml. I want to indent particular lines, while leaving some unindented.
So, I've setted the following String as the document's default CSS:
const QString css = "p.indented{text-indent: 10px} p.normal{text-indent: 0px}";
and, when building the strings to use with setHtml():
QString indentText = "<p class=\"indented\">indented Text</p>"; QString normalText = "<p class=\"normal\">normal Text</p>";
I expected to "indentText" to be indented and "normalText" to stay unindented regardless of the insertion order... But what happens is that the first identation rule to be inserted is applied to all lines inserted after it, even if they have their own text-indent properties.
Is this the expected behaviour in QT?
-
Hi,
Can you show an sample code setting up the css as well as the QTextDocument content ? That way it will be reproducible and testable.
-
Sure:
QTextDocument *doc = new QTextDocument(); QTextCursor cursor(doc); QTextBlockFormat format; doc->setDefaultStyleSheet(css); while(!loglines->isEmpty()) { cursor.insertHtml(loglines->takeFirst()); cursor.insertBlock(); }
"loglines" is a QVector<QString> containg the preformatted lines in HTML
-
Using:
QApplication app(argc, argv); QTextEdit te; QTextDocument *doc = te.document(); QTextCursor cursor(doc); QTextBlockFormat format; const QString css = "p.indented{text-indent: 10px} p.normal{text-indent: 0px}"; doc->setDefaultStyleSheet(css); QVector<QString> loglines = {"<p class=\"indented\">indented Text</p>", "<p class=\"normal\">normal Text</p>"}; while(!loglines.isEmpty()) { cursor.insertHtml(loglines.takeFirst()); cursor.insertBlock(format); } te.show(); return app.exec();
works fine
-
I tried your code again in a standalone project and it worked right.
Looks like it's something related to multithreading.
You see, My application works with big documents (5000+ lines), So, to avoid GUI freezing, I do the QTextDocument building in another thread, and send it to the GUI thread through signal/slot.
So, my "Worker Class" has a slot:
const QString css = "p.indented{text-indent: 10px} p.normal{text-indent: 0px}"; void JsonParser::buildDoc() { QTextDocument *doc = new QTextDocument(); QTextCursor cursor(doc); doc->setDefaultStyleSheet(css); qDebug() << "[JsonParser] Lines translated, building document..."; QVector<QString> loglines = {"<p class=\"indented\">indented Text</p>", "<p class=\"normal\">normal Text</p>"}; while(!loglines.isEmpty()) { cursor.insertHtml(loglines.takeFirst()); cursor.insertBlock(); } emit processingFinished(doc); }
the processingFinished() signal is connected to this slot in my MainWindow Class:
void MainWindow::logReady(QTextDocument *log) { ui->logViewer->setUpdatesEnabled(false); ui->logViewer->setDocument(log->clone(ui->logViewer)); ui->logViewer->setUpdatesEnabled(true); ui->mainToolBar->setEnabled(true); ui->actionAbrir_Log->setEnabled(true); }
Am I missing something?
-
Yes, there's a small but yet important difference: you're not reseting the format between two lines.
-
True, I didn't notice that, sorry!
But looks like it only works for the first two lines...
Even your code, if I add two more lines, like:
QApplication app(argc, argv); QTextEdit te; QTextDocument *doc = te.document(); QTextCursor cursor(doc); QTextBlockFormat format; const QString css = "p.indented{text-indent: 10px} p.normal{text-indent: 0px}"; doc->setDefaultStyleSheet(css); QVector<QString> loglines = {"<p class=\"indented\">indented Text</p>", "<p class=\"normal\">normal Text</p>", "<p class=\"indented\">indented Text</p>", "<p class=\"normal\">normal Text</p>"}; while(!loglines.isEmpty()) { cursor.insertHtml(loglines.takeFirst()); cursor.insertBlock(format); } te.show(); return app.exec();
It shows: screenshot
could you confirm this, @SGaist ?
-
@Tyras
File a bug! I spent some time last night debugging that snippet. I couldn't tell why exactly is not working, but from what I saw you shouldn't be required toinsertBlock()
even. The parser recognizes the<p>
that as a block element and should supposedly insert it for you.
Unfortunately, I doubt you'll get much attention on that bug. If I had to guess, the code for theQTextDocument
class predates even Qt4. Looking at the internal structure, in my opinion, a major refactoring is long overdue.Kind regards.
-
That's bad news for me...
You see, If I don't use html/css, do the formatting using the QTextCharFormat and QTextBlockFormat and use insertText it works fine, but looks like I can't edit a single QTextDocument from multiple threads.
And I can't create nor insert premade QTextBlocks in a QTextDocument, so, the only option to do multithreading editing of the document is using html =/
-
@Tyras said:
but looks like I can't edit a single QTextDocument from multiple threads
Why should that be?
And I can't create nor insert premade QTextBlocks in a QTextDocument, so, the only option to do multithreading editing of the document is using html =/
Look up, I see no reason why you wouldn't be able to do this. Also I don't really know why would you want to thread the document editing, but that's an entirely different affair.
Kind regards.
-