Qt World Summit: Submit your Presentation

Custom painted line on QPlainTextEdit doesn't disappear

  • Hi guys, back from the dead!

    I have a custom class that inherits from QPlainTextEdit. I overloaded the paintEvent() to draw a vertical line that indicates the 80 characters limit. I do it like this:

    void MyCodeEditor::paintEvent(QPaintEvent* event)
        // Base class
        // Draw the ruler (vertical line)
        if (_rulerPositionInChars > 0 && _rulerPositionInPixels > 0) {
            QPainter painter(viewport());
            painter.fillRect(_rulerPositionInPixels, 0, RULER_WIDTH, viewport()->height(), RULER_COLOR);

    The _rulerPositionInPixels is an attribute of the MyCodeEditor class which I set to the correct value inside of my MyCodeEditor::setRulerPosition(int numberOfChars) method. At the end of that method I also call update(). Now, depending on the parameter passed to MyCodeEditor::setRulerPosition() it can happen that the line should no longer be drawn at all. I give the user the ability to dynamically toggle the visibility of the line with a QAction inside a QToolbar above the code editor widget.

    The problem I'm experiencing is that when I set the visibility of the line to false which results in the paintEvent() not painting the line, the lines doesn't disappear until there's new text loaded. But even then, only the blocks (in terms of QTextDocument) that were refreshed erase the line so that sometimes there are just fragments / segments left.

    My question: What do I have to do to make the line genuinely disappear? I tried using QWidget::repaint() instead of QWidget::update() but with no luck.
    I thought that the call the the base class QPlainTextEdit::paintEvent() would take care of clearing the widget area and thus removing the preivously drawn line.

    Any ideas?

  • Lifetime Qt Champion

    Welcome back :)

  • Hi! Just add viewport()->update(); to your paintEvent() override.

  • Oh... well that was stupid...
    Thank you very much, kind Sir. Much appreciated!

  • :) Btw, you don't have to call painter.end(); it's automatically called when painter gets destroyed.

  • Thanks for the remark, I appreciate it!