Results 1 to 19 of 19

Thread: QGraphicsItem leaves junk on screen

  1. #1
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default QGraphicsItem leaves junk on screen

    Hello,
    I am developing an electric cad software with qt4.2 and obviously using QGraphicsView framework
    The problem I am facing is the Wire item - subclass of QGraphicsItem leaves junk on screen when its length or path of wire change rapidly. (Junk ,in the sense, it leaves behind trails of lines on screen). The screenshot attached tells it better.
    Actually this happens when component is moved madly fast. But since my system is pretty high end and sincethere is every possibility of lots of items to be on view, I don't wan't to take a chance.

    The length/path of wire changes when any component connected to wire moves which makes it necessary for the wire to regrow.
    Currently I am achieving this by calling Wire::rebuild in component's itemChange()
    I guess QGraphicsItem:: prepareGeometryChange() is the culprit behind this. Or may be I am doing something wrong in boundingRect() or shape().
    How can I avoid this ?

    Qt Code:
    1. void Wire::rebuild(const QPointF& s, const QPointF& e)
    2. {
    3. //QList<QLineF*> m_lines is member variable
    4. if(!m_lines.isEmpty())
    5. {
    6. qDeleteAll(m_lines);
    7. m_lines.clear();
    8. }
    9.  
    10.  
    11. QPointF st = mapFromScene(s);
    12. QPointF en = mapFromScene(e);
    13.  
    14. if(st.x() == en.x() || st.y() == en.y())
    15. {
    16. m_lines.append(new QLineF(st,en));
    17. prepareGeometryChange();
    18. return;
    19. }
    20.  
    21. QPointF inter = QPointF(st.x(),en.y());
    22. m_lines.append(new QLineF(st,inter));
    23. m_lines.append(new QLineF(inter,en));
    24. prepareGeometryChange();
    25. }
    26.  
    27. QRectF Wire::rectForLine(const QLineF& line) const
    28. {
    29. qreal x = qMin(line.p1().x() , line.p2().x());
    30. qreal y = qMin(line.p1().y() , line.p2().y());
    31. qreal w = qAbs(line.p1().x() - line.p2().x());
    32. if(w < 1.0)
    33. w = 1.0;
    34. qreal h = qAbs(line.p1().y() - line.p2().y());
    35. if(h < 1.0)
    36. h = 1.0;
    37. return QRectF(x,y,w,h);
    38. }
    39.  
    40. QRectF Wire::boundingRect() const
    41. {
    42. QRectF rect(0.0,0.0,0.0,0.0);
    43. foreach(QLineF* line, m_lines)
    44. rect |= rectForLine(*line);
    45. return rect.adjusted(-1.0,-1.0,1.0,1.0);
    46. }
    47.  
    48. QPainterPath Wire::shape() const
    49. {
    50. if(m_lines.isEmpty())
    51. return path;
    52. foreach(QLineF *line, m_lines)
    53. path.addRect(rectForLine(*line));
    54. return path;
    55. }
    To copy to clipboard, switch view to plain text mode 
    Attached Images Attached Images
    Last edited by Gopala Krishna; 14th December 2006 at 17:24. Reason: updated contents

  2. #2
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    124
    Thanked 38 Times in 30 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsItem leaves junk on screen

    You should call prepareGeometryChange() before changing the item's geometry; not after. Try moving the call to the very top of your function, and see what happens.

    If that doesn't remove the problem, could you please try to isolate it, or post a complete example?
    Bitto / Andreas Aardal Hanssen - andreas dot aardal dot hanssen at nokia
    Nokia Software Manager, Qt Development

  3. The following user says thank you to Bitto for this useful post:

    Gopala Krishna (21st December 2006)

  4. #3
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Quote Originally Posted by Bitto View Post
    You should call prepareGeometryChange() before changing the item's geometry; not after. Try moving the call to the very top of your function, and see what happens.

    If that doesn't remove the problem, could you please try to isolate it, or post a complete example?
    Thanks a lot for the tip !!!
    Its working pretty fine after i moved prepareGeometryChange() to top of the function as you said. Thanks again!

  5. #4
    Join Date
    Oct 2006
    Location
    Germany
    Posts
    84
    Thanks
    5
    Thanked 5 Times in 3 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsItem leaves junk on screen

    Hey,
    I was wondering regarding your attached screenshot - what's that at the left side of your application where it says vertically "Components"? Is this some kind of Sidebar or something? Did you do it on your own or does Qt has something like that? Or do you even have it from somewhere else?
    Just curious

  6. #5
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Quote Originally Posted by durbrak View Post
    Hey,
    I was wondering regarding your attached screenshot - what's that at the left side of your application where it says vertically "Components"? Is this some kind of Sidebar or something? Did you do it on your own or does Qt has something like that? Or do you even have it from somewhere else?
    Just curious
    Yes, it is a sidebar(more appropriately toolview). I am using krawek's ideality library - an external library which really makes it easy to use.

  7. #6
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Hi guys,
    Though the wires in my app were moving appropriately the performance was bit low when I tried on my old low end comp. The problem was , one of the lines in wire wasn't being drawn at all when the wires geometry changes rapidly espescially, when lines of wire were perpendicular and lengthy as shown below , where "dash-line" represents undrawn line.
    |
    |
    |
    |
    |_______________________
    The reason I guess is overhead in scene's index management system caused due to repeated "prepareGeometryChange()" calls and also to the fact that the boundingRect coveres unwanted areas resulting in more updates.

    So, I came up with an ugly/good hack by replacing wires with "QRubberBand" of unit width (to represent line) while changing geometry and "QGraphicsLineItem" while static. I hide the QGraphicsLineItem when wire's geometry starts changing and show QRubberBand and vice-versa otherwise . This is working as I expected - fast and clean.
    (I've attached screenshot with QRubberBand "proxying" lines.)

    Do you think this hack is a better alternative or Is there any better way ? Is there any potential problem ?
    Attached Images Attached Images
    Last edited by Gopala Krishna; 30th December 2006 at 18:00. Reason: reformatted to look better

  8. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: QGraphicsItem leaves junk on screen

    Maybe you should turn off BSP indexing while moving objects around? Or if you have composite lines, make them separate objects, so that their bounding rect is much smaller.

  9. #8
    Join Date
    Mar 2007
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsItem leaves junk on screen

    Hi Gopal

    I read your problem that you faced in the past with the wiring two components. I am doing some thing like the same in my application. For the wiring two components, Can you suggest me how to proceed. Do i have to call the wiring class refrence in the Mouse press event of the component classs or ????????????. Please suggest me some thing or send me example some code.

    Thanks alot.
    Rohit

  10. #9
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Hello,
    Quote Originally Posted by rohitjun View Post
    Hi Gopal

    I read your problem that you faced in the past with the wiring two components. I am doing some thing like the same in my application. For the wiring two components, Can you suggest me how to proceed. Do i have to call the wiring class refrence in the Mouse press event of the component classs or ????????????. Please suggest me some thing or send me example some code.

    Thanks alot.
    Rohit
    It depends on how you want to wire the components. It can be done either in the component class or the scene. What I do in my app is, when a component connected to other component is moved, I create an instance of wire in component's mouse move event. When the component is moved further without releasing mouse, I keep updating wire by calling rebuild() in mouse move event itself.
    But I couldn't understand you completely. Sorry for that.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  11. #10
    Join Date
    Jan 2006
    Location
    Norway
    Posts
    124
    Thanked 38 Times in 30 Posts
    Qt products
    Qt3 Qt4 Qt/Embedded
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: QGraphicsItem leaves junk on screen

    In 4.2, there's certainly a hit when reindexing items rapidly. This hit is gone in the upcoming 4.3. Any rendering problems you have had with vertical or horizontal lines should have been fixed in 4.2.3, and is definitely gone in 4.3.

    QRubberBand probably works fine for your case (unless you rotate your view, that is). But with 4.3, I don't think you need it.
    Bitto / Andreas Aardal Hanssen - andreas dot aardal dot hanssen at nokia
    Nokia Software Manager, Qt Development

  12. #11
    Join Date
    Mar 2007
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsItem leaves junk on screen

    Thanks Gopal and Bitto...

    I understood from your code Gopal how to rebuild wiring when the component is moved. But i think i am in the step before of the component move step. Means i am just trying to connect two components through wiring. As to do wiring i have to pass the starting component and ending component in the wiring instance. What i have to impement in the mouse events of the component class to acheive this. I am sorry as i have very few experience of GUI designing.

    Thanks
    Rohit

  13. #12
    Join Date
    Mar 2007
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsItem leaves junk on screen

    Hi

    May be i was not able to make you understand my question last time.

    The two components are not connected in the begining. So when the user want to connect two componets, he has to click the first component and then move the mouse till second component without releasing the mouse and then release the mouse on the second component. Then the wiring will be done. And after that the same what you did...Rebuild the wiring if the component is moved.

    Please suggest
    Thanks
    Rohit

  14. #13
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Quote Originally Posted by Bitto View Post
    In 4.2, there's certainly a hit when reindexing items rapidly. This hit is gone in the upcoming 4.3. Any rendering problems you have had with vertical or horizontal lines should have been fixed in 4.2.3, and is definitely gone in 4.3.

    QRubberBand probably works fine for your case (unless you rotate your view, that is). But with 4.3, I don't think you need it.
    Oh Good news!
    Hey , can I expect good speed while moving about 20*3 items ( each of 20 items move 3 more items ) in Qt 4.3. This is what is challenging to me presently.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  15. #14
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Quote Originally Posted by rohitjun View Post
    Hi

    May be i was not able to make you understand my question last time.

    The two components are not connected in the begining. So when the user want to connect two componets, he has to click the first component and then move the mouse till second component without releasing the mouse and then release the mouse on the second component. Then the wiring will be done. And after that the same what you did...Rebuild the wiring if the component is moved.

    Please suggest
    Thanks
    Rohit
    Ok I get it now.
    When a component is moved and placed(after mouse release) on other component, I simply add the new componet in the component's list of the corresponding node and store the connection status. I dont create wire here.

    Next when the user moves any one of these components , I create a new node and update the connections. Then I create a wire between these two nodes.
    If the wire exist beforehand, I just keep updating the wire's geometry ( in mycase I call rebuild() )
    And yes I do all this in scene's subclass since I need to keep track of everything for undo/redo.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  16. #15
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Quote Originally Posted by rohitjun View Post
    Thanks Gopal and Bitto...

    I understood from your code Gopal how to rebuild wiring when the component is moved. But i think i am in the step before of the component move step. Means i am just trying to connect two components through wiring. As to do wiring i have to pass the starting component and ending component in the wiring instance. What i have to impement in the mouse events of the component class to acheive this. I am sorry as i have very few experience of GUI designing.

    Thanks
    Rohit
    What you can do is the moment the component is placed on another , update the connection status of both the components. Probably you can create 0 length wire. You need to store locations of connection points in wire object.
    When the user moves any of this component , update both the end points in wire (if you don't know how to please ask) and just rebuild the wire(). Probably you can implement in mouse events of Component
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  17. #16
    Join Date
    Mar 2007
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsItem leaves junk on screen

    Thanks for the help Gopal.

    Your reply is very helpful for my understanding.

    But one more thing, The components are not moved.

    I created a shape of And_gate having input and output connectors. I have to connect the output of one And_gate to the input of the another And_gate. The And_gate is movable but not the connector (Connector is attached with the And_gate so it will move when And_gate is moved). And i have to connect the connecotrs and store the And_Gate information with their connections.

    Rohit

  18. #17
    Join Date
    Mar 2007
    Posts
    21
    Thanks
    1
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: QGraphicsItem leaves junk on screen

    I am explaining my problem again below...Gopal

    Suppose there are two Gates in the GUI having one input and one output connector. I should be able to connect the Gates with the wire (Means output connector of one Gate with the input connector of the other Gate). The wiring will done this way...The user will take the mouse on the output connector of the one gate and then with out releasing the mouse, the user will go to the input connector of the other Gate and then release the mouse.The wiring will be visible in the GUI.

    This is similar procedure as LabVIEW uses(Just for your info).
    Rohit

  19. #18
    Join Date
    Aug 2006
    Location
    Bangalore,India
    Posts
    419
    Thanks
    37
    Thanked 53 Times in 40 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: QGraphicsItem leaves junk on screen

    Quote Originally Posted by Bitto View Post
    In 4.2, there's certainly a hit when reindexing items rapidly. This hit is gone in the upcoming 4.3. Any rendering problems you have had with vertical or horizontal lines should have been fixed in 4.2.3, and is definitely gone in 4.3.

    QRubberBand probably works fine for your case (unless you rotate your view, that is). But with 4.3, I don't think you need it.
    I had forgotten to report my experiment.
    Even with qt-4.3 there is "not so great" performance. But ofcourse the problem is worst only when the wire's bounding rect is huge (say rect of size 800x600) and the wire is being moved constantly.

    As a result, i still stick on to using rubberband as the view isn't rotated throughout.
    The biggest difference between time and space is that you can't reuse time.
    -- Merrick Furst

  20. #19
    Join Date
    Oct 2006
    Location
    New Delhi, India
    Posts
    2,467
    Thanks
    8
    Thanked 334 Times in 317 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QGraphicsItem leaves junk on screen

    Hi, havent read ur long messages.,,,,
    but a thing came to my mind.. have u tried using shape() with boundingRect() ?? shape() defines the actual area/shap of ur item, so it help in speed,,, i guess
    am not so sure of it,,, but u can give it a try

Similar Threads

  1. destruction of QGraphicsItem
    By killkolor in forum Qt Programming
    Replies: 2
    Last Post: 5th December 2009, 10:31

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.