[SOLVED] bug in QGraphicsItem.update() ???



  • I have written a little program to rectivy images taken under an angle from a phosphor screen. The program uses a custom QGraphicsItem (ringItem - a mask of rings) to test the rectification and to calibrate a scale in the rectivied images. This workes all good, I can use for each image (in several tabs) a QGraphicsScene-object with a ringItem. But if I have opend a image with a ringItem and than want to import (rectify) a new Image (which opens an additional window with a QGraphicsScene + a ringItem ), the program hangs. I have searched many hours to find the reason for this behavior. Finally I found the problem in the paint()-method of my QGraphicsItem . There I have to call update(). It seems, if there are two windows with two QGraphicsScenes the call of update not only updates Items in the own QGraphicsScene but also the overlapped Items in the other QGraphicsScene of the other window, leading to a infinite loop.
    Is this behavior intended? I would have expected, that update only influences Items in the same QGraphicsScene. Or could this be a bug?


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Why do you need to call update in your paint function ?



  • Well, the ringsItem can change in size (by keyboard or via other parts of the UI) and also the boundingRect has to be recalculated, so that the "klick-area" is correct. I'm not sure why exactly I used update(), but without it, the rings aren't redrawn if I change radius, lattice or other parameters. I'm new to Qt and C++ (ok 10 years ago I had some lectures about C++ - but as far as I recall these didn't even cover classes ^^) and this is my first program with Qt, so the best thing would be to show you my program code. But the project is too large, to post all the code in a forum. I can give you the shortend paint-method:
    @
    void DiffRingsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
    painter->setPen(QPen(Qt::red,2));

    Qt::KeyboardModifiers keyMod = QApplication::keyboardModifiers ();
    bool isSHIFT = keyMod.testFlag(Qt::ShiftModifier);
    bool isCTRL = keyMod.testFlag(Qt::ControlModifier);
    if (isCTRL && (lattice != cal_Lattice))
      painter->drawPoint(x_Center, y_Center);
    else if (isCTRL)
      painter->drawPoint(x_calCenter, y_calCenter);
    
    if (hasFocus()) {
        painter->setPen(QPen(Qt::green, 2));
    }
    
    double r;
    
    if (lattice == fcc_Lattice)
    {
        for (int i=1; i<=20; i++)
        {
            if (i==3 || i==4 || i==8 || i==11 || i==12 || i==16 || i==19 || i==20)
            {
                r = (sqrt(i)/a) *calibrationFactor * cameraFactor;
                painter->drawEllipse((x_Center-r), (y_Center-r), 2*r, 2*r);
            }
        }
    
    } else if (lattice==bcc_Lattice)
    {
        for (int i=1; i<=16; i++)
        {
          // ...
        }
    } else if (lattice==cal_Lattice)
    {  
      // ... 
    }
    if (r!=r_max){
        prepareGeometryChange();
        r_max=r;
    }
    update();
    

    }

    QRectF DiffRingsItem::boundingRect() const
    {
    if (lattice==cal_Lattice) {
    return QRectF((x_calCenter-r_max), (y_calCenter-r_max), 2r_max, 2r_max);
    } else
    return QRectF((x_Center-r_max), (y_Center-r_max), 2r_max, 2r_max);

    }
    @


  • Lifetime Qt Champion

    AFAIK you should call update when you modify any of the parameters of your DiffRingsItem, it should be enough.



  • Good point, I will try that. Thanks.
    Nevertheless I'm curious why update() would force a repaint in another scene of another window, and if this is the intended behavior. But maybe I will look into this, when I'm a little bit more experienced.


Log in to reply
 

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