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.


  • Qt Champions 2016

    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


  • Qt Champions 2016

    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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.