QTextEdit and "carriage-return" / "\r" character
-
I am using a (multi-line, scrollable)
QTextEdit
widget to display the grabbed output from aQProcess
in real-time.One process deliberately embeds a
\r
(carriage-return) characters in its output --- it's outputting a "progress" something like:10%\r20%\r30% ...
This is a common thing for command-line programs to do: in a terminal this avoids occupying multiple lines because the
\r
jumps back to the start of the current line and overwrites what's there.When I blindly send this raw output --- along with everything else --- to
QTextEdit::append()
the user sees multiple lines instead, making the output look voluminous.[EDIT: Hmm, it's a bit confusing. What I actually seem to see is an extra blank line between items, like:
10 20 30
]
- I take it that
QTextEdit
is not going to handle\r
by returning to the start of a line, right? - If I want the "nice" behaviour, I would have to do shenanigans along the lines of parsing the output, locating the
\r
s, and then not just simply appending but rather actually replacing the previous last line which was added, right? - Assuming that would be required, it's more code than it's worth. The best might be to blindly remove any
\r
s before sending toQTextEdit
: I wouldn't get the "overwrite" behaviour, I'd get one great long line, but that might be preferable to multiple lines for the user in the output, right?
- I take it that
-
I am using a (multi-line, scrollable)
QTextEdit
widget to display the grabbed output from aQProcess
in real-time.One process deliberately embeds a
\r
(carriage-return) characters in its output --- it's outputting a "progress" something like:10%\r20%\r30% ...
This is a common thing for command-line programs to do: in a terminal this avoids occupying multiple lines because the
\r
jumps back to the start of the current line and overwrites what's there.When I blindly send this raw output --- along with everything else --- to
QTextEdit::append()
the user sees multiple lines instead, making the output look voluminous.[EDIT: Hmm, it's a bit confusing. What I actually seem to see is an extra blank line between items, like:
10 20 30
]
- I take it that
QTextEdit
is not going to handle\r
by returning to the start of a line, right? - If I want the "nice" behaviour, I would have to do shenanigans along the lines of parsing the output, locating the
\r
s, and then not just simply appending but rather actually replacing the previous last line which was added, right? - Assuming that would be required, it's more code than it's worth. The best might be to blindly remove any
\r
s before sending toQTextEdit
: I wouldn't get the "overwrite" behaviour, I'd get one great long line, but that might be preferable to multiple lines for the user in the output, right?
@JNBarchan i think you get an empty line as \r is translated to \n in QTextEdit.
append()
itself adds another line break.the easiest way would be
QString::trimmed()
before appending.if you like to simulate carriage return, you would need to replace the last line instead appending if your line contains \r (you would remove the \r nevertheless). not sure how fluent that would look, though.
- I take it that
-
@JNBarchan i think you get an empty line as \r is translated to \n in QTextEdit.
append()
itself adds another line break.the easiest way would be
QString::trimmed()
before appending.if you like to simulate carriage return, you would need to replace the last line instead appending if your line contains \r (you would remove the \r nevertheless). not sure how fluent that would look, though.
append()
itself adds another line break.Hmm, where's that documented?** Because I'm receiving "chunks" of output from the subprocess, I want to add exactly what I get from there without extra newlines etc. Is there any different between
QTextEdit.append(newStuff)
versusQTextEdit.setText(QTextEdit().getText() + newStuff)
in this "another line break" respect?** EDIT: OK, I'm seeing the documentation for
QTextEdit.append()
is talking about "paragraphs" and things. I had not intended that: I just want the quickest way to append some new text to whatever is there exactly. I can now see thatQTextEdit.setPlainText(QTextEdit().toPlainText() + newStuff)
is getting rid of unwanted blank lines (that's good, though it looks "inefficient"?).the easiest way would be
QString::trimmed()
before appending.Does me no good. Because I get "chunks of output" as a single string (byte array actually), the
\r
s are embedded all over the place in the middle of stuff. That's why I'd have to scan the string to do my work. At the moment I've just put instr.replace("\r", "")
, and now at least I'm not getting the blank lines.if you like to simulate carriage return, you would need to replace the last line instead appending if your line contains \r (you would remove the \r nevertheless). not sure how fluent that would look, though.
Yes, and that would mean looking at my existing content to determine where "the last line" starts, and recognising multiple lines with
\r
in them in what is to be "appended", and I can't be bothered with the whole thing! -
append()
itself adds another line break.Hmm, where's that documented?** Because I'm receiving "chunks" of output from the subprocess, I want to add exactly what I get from there without extra newlines etc. Is there any different between
QTextEdit.append(newStuff)
versusQTextEdit.setText(QTextEdit().getText() + newStuff)
in this "another line break" respect?** EDIT: OK, I'm seeing the documentation for
QTextEdit.append()
is talking about "paragraphs" and things. I had not intended that: I just want the quickest way to append some new text to whatever is there exactly. I can now see thatQTextEdit.setPlainText(QTextEdit().toPlainText() + newStuff)
is getting rid of unwanted blank lines (that's good, though it looks "inefficient"?).the easiest way would be
QString::trimmed()
before appending.Does me no good. Because I get "chunks of output" as a single string (byte array actually), the
\r
s are embedded all over the place in the middle of stuff. That's why I'd have to scan the string to do my work. At the moment I've just put instr.replace("\r", "")
, and now at least I'm not getting the blank lines.if you like to simulate carriage return, you would need to replace the last line instead appending if your line contains \r (you would remove the \r nevertheless). not sure how fluent that would look, though.
Yes, and that would mean looking at my existing content to determine where "the last line" starts, and recognising multiple lines with
\r
in them in what is to be "appended", and I can't be bothered with the whole thing!@JNBarchan said in QTextEdit and "carriage-return" / "\r" character:
append()
itself adds another line break.Hmm, where's that documented?
http://doc.qt.io/qt-5/qtextedit.html#append :
Appends a new paragraph with text to the end of the text edit.Because I'm receiving "chunks" of output from the subprocess, I want to add exactly what I get from there without extra newlines etc.
Understand.
Is there any different between
QTextEdit.append(newStuff)
versusQTextEdit.setText(QTextEdit().getText() + newStuff)
in this "another line break" respect? I guessQTextEdit.append(newStuff)
would be something likeQTextEdit.setText(QTextEdit().getText() + '\n' + newStuff)
You could try http://doc.qt.io/qt-5/qtextedit.html#insertPlainText . It might be faster than calling
setText()
all over again. Thats also what QtCreator does in the Application and Compile Output windows.the easiest way would be
QString::trimmed()
before appending.Does me no good. Because I get "chunks of output" as a single string (byte array actually), the
\r
s are embedded all over the place in the middle of stuff.Ok, yes in that case
trimmed()
is not enough.That's why I'd have to scan the string to do my work. At the moment I've just put in
str.replace("\r", "")
, and now at least I'm not getting the blank lines.If you want a simple solution, than you could stick with this.
-
@JNBarchan said in QTextEdit and "carriage-return" / "\r" character:
append()
itself adds another line break.Hmm, where's that documented?
http://doc.qt.io/qt-5/qtextedit.html#append :
Appends a new paragraph with text to the end of the text edit.Because I'm receiving "chunks" of output from the subprocess, I want to add exactly what I get from there without extra newlines etc.
Understand.
Is there any different between
QTextEdit.append(newStuff)
versusQTextEdit.setText(QTextEdit().getText() + newStuff)
in this "another line break" respect? I guessQTextEdit.append(newStuff)
would be something likeQTextEdit.setText(QTextEdit().getText() + '\n' + newStuff)
You could try http://doc.qt.io/qt-5/qtextedit.html#insertPlainText . It might be faster than calling
setText()
all over again. Thats also what QtCreator does in the Application and Compile Output windows.the easiest way would be
QString::trimmed()
before appending.Does me no good. Because I get "chunks of output" as a single string (byte array actually), the
\r
s are embedded all over the place in the middle of stuff.Ok, yes in that case
trimmed()
is not enough.That's why I'd have to scan the string to do my work. At the moment I've just put in
str.replace("\r", "")
, and now at least I'm not getting the blank lines.If you want a simple solution, than you could stick with this.
http://doc.qt.io/qt-5/qtextedit.html#append :
Appends a new paragraph with text to the end of the text edit.You could try http://doc.qt.io/qt-5/qtextedit.html#insertPlainText . It might be faster than calling setText() all over again
Yes, I had put an EDIT into my post as I came to realise these. It turns out most of the "ugliness" was actually due to blank line from each
append()
. Now withsetText()
always instead, it doesn't look too bad.Qt doesn't offer any "raw" append? In native Windows (and maybe HTML/JS too), when I want to append like this I go something like "caret to end" and then "insert characters". I assume that helps with scroll smoothness/no redraw, whereas
setText()
is going to rewrite the whole control each time? Since I'm gathering external output, there could be like a megabyte there and I just get one more line at a time to append....I've decided now to just leave any
\r
s in the output as-is. They go to next line, but removing them just results in a very long line anyway, so it's a matter of opinion either way. It leaves my code more generic & simple. -
I have noticed this behavior. The append(...) option will add a line break but insert(...) will not. I would go with inset(...) unless you are processing the text to manually separate all appends calls to separate lines of text. QString::split('/r'); will work nicely to separate into individual lines.
If you use the insert(...) option you need to make sure the cursor at the end otherwise the new text could appear in the middle of the document. A simple mouse click will move the insert position.
Reading back all the text, adding new text, then calling setText(...) doesn't sound efficient.
-
I have noticed this behavior. The append(...) option will add a line break but insert(...) will not. I would go with inset(...) unless you are processing the text to manually separate all appends calls to separate lines of text. QString::split('/r'); will work nicely to separate into individual lines.
If you use the insert(...) option you need to make sure the cursor at the end otherwise the new text could appear in the middle of the document. A simple mouse click will move the insert position.
Reading back all the text, adding new text, then calling setText(...) doesn't sound efficient.
@Rondog
Ah, OK, I simply had not noticed there is aQTextEdit::insertPlainText()
. I had seenQTextEdit::setText()
&QTextEdit::append()
. I'm familiar with having to position the cursor for appending with insert. I seeQTextEdit::moveCursor()
.This sounds like I'd expect instead of resetting whole text! Thanks.
-
I have noticed this behavior. The append(...) option will add a line break but insert(...) will not. I would go with inset(...) unless you are processing the text to manually separate all appends calls to separate lines of text. QString::split('/r'); will work nicely to separate into individual lines.
If you use the insert(...) option you need to make sure the cursor at the end otherwise the new text could appear in the middle of the document. A simple mouse click will move the insert position.
Reading back all the text, adding new text, then calling setText(...) doesn't sound efficient.
@Rondog
I have now simply set my append code to:# append further text at the end, efficiently self.text.moveCursor(QtGui.QTextCursor.End) self.text.insertPlainText(moreText)
This also seems to scroll to the end for me, avoiding the need for me to explicitly call set the vertical scrollbar's position.Sometimes it scrolls to end, but not always. Since I want scroll-to-end (and the widget is read-only, so no visible cursor), I have appended:
sb = self.text.verticalScrollBar() sb.setValue(sb.maximum()) `` Thanks to all.