Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QPainter / QPixmap : problem erasing antialiased lines



  • Hello,

    I would like to erase a previously drawn line in a QPixmap. Here is little sample code to demonstrate the problem:

    void Widget::paintEvent(QPaintEvent *)
    {
        QPainter p(this);
        QPixmap px(size());
    
        px.fill(Qt::transparent);
    
        QPainter p2(&px);
        p2.setRenderHint(QPainter::Antialiasing, true);
        p2.setPen(Qt::red);
        p2.drawLine(100, 100, 200, 200);
        p2.setCompositionMode(QPainter::CompositionMode_Clear);
        p2.drawLine(100, 100, 200, 200);
    
        p2.end();
    
        p.drawPixmap(0, 0, px);
        // no line should be drawn in the widget
    }
    

    When I run this code, the widget contains a semi transparent red line.
    Here is the screenshot

    If I deactivate the antialiasing, everything works fine : the line is properly erased from the pixmap.

     p2.setRenderHint(QPainter::Antialiasing, false);
    

    Anybody can tell me what I'm doing wrong ?

    Thank you in advance,
    Best regards
    Vincent



  • Hi,
    probably it should work as you expects. But as it does not I would resort to the usual way to do this:
    if you want the transparent line removed from the widget simply draw the whole widget anew without the line.
    -Michael.


  • Lifetime Qt Champion

    Hi
    Not tested myself but did you try with
    setCompositionMode(QPainter::RasterOp_SourceXorDestination);



  • Yes, Xor-mode is the other way (a fast way) to do this. Then you would already draw the original line in Xor-mode and redraw it in Xor-mode in exactly the same way as before to get rid of it again.
    But beware: lines drawn in Xor-mode look in a way your users have to get accustomed to :-)



  • Thank you for your help,

    @m-sue
    For performance reasons, I cannot redraw the entire widget. I draw a lot of line in a pixmap (representing the curve of an analogic signal over time : it can be one hour of data). I optimise my code to only draw needed lines but sometimes I have to redraw a line to reflect signal changes.

    @mrjj
    As Qt doc says turning on the QPainter::Antialiasing render hint will effectively disable the RasterOp modes. So I cannot use this flag to erase the line

    Regards
    Vincent


  • Lifetime Qt Champion

    Oh, Its simply not supported to
    mix Antialiasing and xor style.
    Ok no use then. Was just a thought.
    Good you do in fact read the docs :)

    If full repaint is too expensive, what about dirty rect ? If you need to redraw a line, delete bounding box
    then you redraw all lines affected. (also if partial in .)


Log in to reply