QTextEdit delete whole line at given position

You can remove the line at lineNumer with :

QTextCursor cursor = textEdit->textCursor();

cursor.movePosition(QTextCursor::Start);
cursor.movePosition(QTextCursor::Down, QTextCursor::MoveAnchor, lineNumer);
cursor.select(QTextCursor::LineUnderCursor);
cursor.removeSelectedText();
cursor.deleteChar(); // clean up new line

textEdit->setTextCursor(cursor);

Here you put the cursor at the beginning of the document, move down lineNumer times, select the specific line and remove it.


I know that this question has been accepted and that it's fairly dead here, but I'm going to posit my experiences with QTextEdit as a caution to those that follow.

My problem space was similar to OP's in that I wanted to remove a single line from a text edit. I following the given solution here, improving upon it slightly, and ultimately believed that I had found success.

That success, however, was only realized while the text edit was being viewed, or if it had appeared on screen at least once throughout the course of the program. While I cannot confirm this, I believe that it has to do with cursor manipulation.

Here's a more in-depth explanation:

I desired to create a message history between a UI and the remote unit to which it was conversing. The messages would be color-coded, one for the UI's sent messages, the other for the received messages. In order to prevent a massive memory impact, the idea is to limit the number of lines to a specific amount, say 1000.

My original code was much like the accepted answer:

  • If the number of lines exceeded my setpoint, move cursor to the beginning and delete the first line.

After some time, however, I began to notice a slowdown in the runtime execution of the program. After adding debug in, I found that, so long as I had not actually viewed the location to which the text was sent, the line-limiter never actually erased the lines. The QTextEdit to which the text was sent was in a tabbed widget. This means that I had to cycle through to that tab, otherwise the algorithm wouldn't work.

Here is a working solution for my problem space:

void ScrollingEdit::append(QString text, QColor color)
{
    QString pc = QString("<body style=\"color:rgb(%1,%2,%3);\">").
        arg(color.red()).arg(color.green()).arg(color.blue());
    QString ac = QString("</body>");

    text.prepend( pc );
    text.append( ac );

    mText.append( text );

    QString delim = "</body>";

    if ( mText.count( delim ) > mMaxLine )
    {
        mText.remove(0, mText.indexOf( delim ) + delim.size() );
    }

    mEdit->clear();
    mEdit->setHtml( mText );

    QTextCursor cursor = mEdit->textCursor();

    cursor.movePosition( QTextCursor::End );

    mEdit->setTextCursor(cursor);
    mEdit->ensureCursorVisible();
}

Where mText is a member variable QString that acts as the "model" for the text edit, mMaxLine is a user-configurable int that sets the maximum number of allowable lines, and mEdit is the UI QTextEdit. Note that cursor manipulation still exists, but where it matters, which is when the user is viewing the element.


You can do the following:

QTextEdit te;
// Three lines in the text edit
te.setText("Line 1\nLine 2\nLine 3");

const int lineToDelete = 1; // To delete the second line.
QTextBlock b = te.document()->findBlockByLineNumber(lineToDelete);
if (b.isValid()) {
    QTextCursor cursor(b);
    cursor.select(QTextCursor::BlockUnderCursor);
    cursor.removeSelectedText();
}