[SOLVED]-How can I draw XOR lines in a QGraphicsScene?



  • [Edit] I changed the title so it looks like a question and not a how to piece!

    Or any other paint device...

    I am looking in the documentation for hints as to how to do this but it does not seem obvious. I guess I must implement the paint function for a custom QGraphicsItem but I can't figure out how to draw a line in XOR style so it will always be visible when drawn over other items (except for the case of something with a 50% grey colour perhaps).

    I would be very grateful for any advice about how to do this.

    Thanks



  • OK, so no takers on this question then...

    A little more investigation shows that other folks have had issues with this.
    "as you can see here":http://www.qtforum.org/article/23564/xor-painting.html

    I mean... this is one of the most common things you need from a graphics library. I looks like it used to be trivial back in the days of Qt 3.? As the link above mentions.

    So why was it made non trivial? I would love to know the reasoning behind that!

    I still need to figure out the best way to do this. I am looking at implementing this in a cutstom GQraphicsItem using image copying with the CompositionMode for the XOR business.

    I am having some problems copying the image back to the scene as it will not go back to the correct place. I think this is a transformation issue but since I am making a graphic item I thought I only had to be concerned with the local item coordinates??? I will probably post some code later...

    In the mean time, does anyone have any thoughts about this???
    Does anyone know of any examples.

    Thanks


  • Moderators

    as you may already found yourself it's only possible with "QPainter's composition modes":http://qt-project.org/doc/qt-4.8/qpainter.html#composition-modes
    But these are only working on images.
    I think it's not possible what you want to achieve. What are you exactly trying to do? Maybe there is another solution for what you want to achieve.



  • Thank you for your kind reply raven-works,

    Yes I have found that I must use the QPainter composition modes to do this. I have heard from other sources that these only work on images. The documentation says that they work for pens and brushes etc. but it seems there are limitations in various cases but I don't have time to check them all out right now. I am only interested in drawing with XOR .

    Now, I have done some prototypes and founds some interesting things. Yes they do work with images a QImage to be exact. And it works very well however I don't like the idea of grabbing the screen and copying it back every time I draw rubberband object . It is not slow, even with a full screen window but it seems a bit too much to me.

    I eventually found that I don't actually need to copy the screen under to do this. It seems to work by setting the CompositionMode to QPainter::RasterOp_NotSourceXorDestination and just drawing into the scene with the painter. I also figured out how to do it using an QGLWidget as the viewport.

    Here is the paint function of my GraphicsItem.

    @
    void RBLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget widget)
    {
    if( qobject_cast<QGLWidget
    >(widget) != 0 )
    {
    painter->beginNativePainting();
    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_COLOR_LOGIC_OP);
    glLogicOp(GL_XOR);

        glLineWidth(pen().widthF());
        glPointSize(pen().width());
        glBegin(GL_POINTS);
            glVertex2d(line().p1().x(),line().p1().y());
            glVertex2d(line().p2().x(),line().p2().y());
        glEnd();
        glBegin(GL_LINES);
            glVertex2d(line().p1().x(),line().p1().y());
            glVertex2d(line().p2().x(),line().p2().y());
        glEnd();
    
        glDisable(GL_COLOR_LOGIC_OP);
        painter->endNativePainting();
    }
    else
    {
        QPainter::CompositionMode lastMode = painter->compositionMode();
        painter->setCompositionMode(QPainter::RasterOp_NotSourceXorDestination);
        painter->setPen(pen());
        painter->drawLine(line());
        painter->setCompositionMode(lastMode);
    }
    

    }
    @

    I am currently using both a QWidget and a QGLWidget in different QGraphicsView objects showing the same scene. My rubberband objects must work on both types hence the code for both in the paint function.

    I am not totally certain why this works but it seems to work well on both Windows and the Mac. I am a bit concerned that it is only working because of a bug and it will stop working when some new version comes along :-O

    I hope some of you experts out there can advise me on this...

    Thanks


Log in to reply
 

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