Results 1 to 4 of 4

Thread: qgraphicslineitem displaying full width or height of view

  1. #1
    Join Date
    Nov 2009
    Location
    San Antonio, TX
    Posts
    69
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt Jambi
    Platforms
    Unix/X11 Windows

    Default qgraphicslineitem displaying full width or height of view

    I have a QGraphicsView that is showing some data. The user wants to be able to lay down some "markers" on this view that stretch the full length of the viewport, either full width or full height. The user also wants to be able to move these markers.

    I thought of starting with the QGraphicsLineItem, but I am not sure how to set the width or height based on the viewport since the line item is held in scene coordinates. I need this to work on any scaling of the scene. Also, I believe I will need a small buffer around the line to make it easier to grab, but again this is in scene coordinates . . . would just like to add a couple of pixels on either side of line.

    So, is QGraphicsLineItem the way to go or do I implement something within the view itself to control the markers and their drawing?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qgraphicslineitem displaying full width or height of view

    I faced a similar problem where I needed to overlay labels (of fixed size, independent of the scene scaling) onto the viewport in such a way that collisions among labels were eliminated. Which labels are displayed of course depends on the region of the scene being displayed in the view, so I couldn't use collision detection at the scene level.

    The way I solved this was to use two scenes: one that could be shared among multiple views, and a view-specific scene dedicated and owned by each view. I derived a custom QGraphicsView class, and created the overlay scene in its constructor. I then reimplemented the QGraphicsView::drawForeground() method, and in that, I render the dedicated scene.

    With this method, you can use QGraphicsItem types in the dedicated scene with all the benefits of scaling, rotation, etc. The major tricky bit is you need to synchronize the world coordinates of the dedicated scene to match the portion of the world displayed in the viewport.

    Thanks to Wysota for suggesting this idea in this thread, following up on a question first posed in this thread.

  3. #3
    Join Date
    Nov 2009
    Location
    San Antonio, TX
    Posts
    69
    Thanked 1 Time in 1 Post
    Qt products
    Qt4 Qt Jambi
    Platforms
    Unix/X11 Windows

    Default Re: qgraphicslineitem displaying full width or height of view

    The way I solved this was to use two scenes: one that could be shared among multiple views, and a view-specific scene dedicated and owned by each view. I derived a custom QGraphicsView class, and created the overlay scene in its constructor. I then reimplemented the QGraphicsView::drawForeground() method, and in that, I render the dedicated scene.
    hmm, that is an interesting concept. I asume you used some form of the draw items section of the QGraphicsView paintEvent method to draw the dedicated scene . . . and adjusting the transform based on multi-view scene and calling drawItems of scene.

    With this method, you can use QGraphicsItem types in the dedicated scene with all the benefits of scaling, rotation, etc.
    But if I do not need any of the benefits of the scene transform (all I need is position), is storing them in a dedicated scene the right place?

    I also have a need to be able to move the items in the view. If these items are rendered from the dedicated scene, do I have access to grab and move them? Do I need to pass the mouse events to the dedicated scene first or will I need to implement the mouse controls in the view?

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: qgraphicslineitem displaying full width or height of view

    I asume you used some form of the draw items section of the QGraphicsView paintEvent
    No, as I said, I implemented QGraphicsView::drawForeground() in my derived class, and call QGraphicsScene::render() on the captive scene.

    But if I do not need any of the benefits of the scene transform (all I need is position), is storing them in a dedicated scene the right place?
    It makes life easier, because these are view-specific items and can't be part of the generic scene. If you never intend to share the same scene with multiple views, then you can simply put them in the main scene and scale them appropriately. But if you will be displaying the same scene in several places, with potentially different viewports and scales, then you need to use a different mechanism. I found this easier to implement. The guts of it are dead simple:

    Qt Code:
    1. void CustomView::drawForeground( QPainter * pPainter, const QRectF & rect )
    2. {
    3. QGraphicsView::drawForeground( pPainter, rect );
    4. mForegroundScene.render( pPainter, rect, QRectF(), Qt::IgnoreAspectRatio );
    5. }
    6.  
    7. void CustomView::onSceneRectChanged( const QRectF & rect )
    8. {
    9. setSceneRect( rect );
    10. mForegroundScene.setSceneRect( rect );
    11. }
    12.  
    13. void CustomView::onZoomed( const QRectF & zoomRect )
    14. {
    15. QRectF canvasRect = rect();
    16.  
    17. double xScale = ( canvasRect.width() / zoomRect.width() );
    18. double yScale = ( canvasRect.height() / zoomRect.height() );
    19.  
    20. resetTransform();
    21. centerOn( zoomRect.center() );
    22. scale( xScale, yScale );
    23.  
    24. mForegroundScene.setSceneRect( zoomRect.normalized() );
    25. }
    To copy to clipboard, switch view to plain text mode 

    where CustomView is derived from QGraphicsView and has a QGraphicsScene mForeGroundScene member variable. The onSceneRectChanged is connected to the shared scene's sceneRectChanged() signal, onZoomed() is a slot connected to a zoomed() signal emitted by the QWidget-based class that holds the CustomView instance in a layout.

    Do I need to pass the mouse events to the dedicated scene first or will I need to implement the mouse controls in the view?
    Good question, and I will eventually have to solve it because I will have the same need in my CustomView.

    I am not sure how you would implement mouse interaction, except by doing it in the view itself. The foreground scene doesn't really have any views associated with it (including the one that owns it), so it won't receive any mouse events. I assume you could forward the view's events to the foreground scene or perhaps simply query the foreground scene for any items it contains at the given mouse position.

    Perhaps Wysota has already solved this one too

    P. S. There's actually more to this custom view than the above - I also implemented the drawBackground() method and added the optional ability to display a QPixmap as an underlay to data graphics and markers drawn above it in the main scene and the overlay scene. The purpose of this whole exercise was to implement a Qwt-style data plotting widget that uses a QGraphicsView as its central canvas. The background pixmap could represent a biological image, like a micrograph of a cell. I might want to overlay that with labels for different parts of the cell, line plots to show the concentration of certain chemicals, and so forth. The same scene data might be viewed in multiple windows, at different magnification scales or locations, so there are things that are scene-specific and other things that are view-specific. The mechanism suggested by Wysota seemed like a flexible way to support all those layers.
    Last edited by d_stranz; 21st March 2013 at 22:34.

Similar Threads

  1. Widget Height and Width
    By in_dbasu in forum Qt Programming
    Replies: 3
    Last Post: 11th August 2011, 08:44
  2. Replies: 1
    Last Post: 25th February 2011, 11:46
  3. Updating the width/height of a QGraphicsItem
    By blooglet in forum Qt Programming
    Replies: 1
    Last Post: 10th February 2011, 14:03
  4. Replies: 1
    Last Post: 23rd April 2009, 09:05
  5. width and height of QTabWidget
    By chikkireddi in forum Qt Programming
    Replies: 6
    Last Post: 29th October 2007, 13:53

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.