Results 1 to 9 of 9

Thread: How to make some items non movable on scene

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Mar 2013
    Posts
    11
    Thanks
    6
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default How to make some items non movable on scene

    I have a QGraphicsscene which shows a plot with X and Y axis..When user zooms the plot...I want only curve to be zoomed and axis should be fixed at their original position.I have tried using Qt::itemIgnoresTransformation flag for X and Y axis ,,,but X and Y axis are still moving with zooming(with flag set they dont move propotional to zoom factor but they dont stay at their original position).Has anybody come across similar problem with qgraphicsscene?

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,321
    Thanks
    316
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to make some items non movable on scene

    Has anybody come across similar problem with qgraphicsscene?
    Yes. It is difficult to implement an x-y data plot using graphics / view for the whole thing because of these scaling problems.

    My solution was to use graphics / view [I]only for the canvas[I] (the region containing the data curves). The axes, titles, etc. were ordinary QWidgets (a custom axis widget, and standard QLabel for titles). The composite widget that holds all of these sub-widgets handles the layout, zooming, resizing, etc.

    The canvas needs to send signals when zooming occurs. The composite widget is connected to these signals and sets the axis ranges appropriately.

    Search for other posts under my name and you will see detailed discussions of how to solve the problem as well as that of keeping labels on the plot the same size even when the plot is zoomed.

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

    tarunrajsingh (3rd April 2013)

  4. #3
    Join Date
    Nov 2010
    Posts
    315
    Thanked 53 Times in 51 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows Symbian S60 Maemo/MeeGo

    Default Re: How to make some items non movable on scene

    This is simple to solve. Everything what should be scaled should have a common parent widget, and axises shouldn't have such parent.
    Three of objects should look like this:
    MainWidget
    Lauout
    AxisX
    AxisY
    ScaleWidget (it doesn't show own content it is a parent for object to scale, here you apply a transformation)
    element 1 to scale
    element 2 to scale

  5. #4
    Join Date
    Mar 2013
    Posts
    11
    Thanks
    6
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: How to make some items non movable on scene

    Thanks for the suggestion ...I would try that.Is this a bug in QgraphicsView because in general anyone can end up in a situation where some part of the scene needs to be zoomed and some needs to be static on some mouse action.

  6. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,321
    Thanks
    316
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to make some items non movable on scene

    Is this a bug in QgraphicsView
    No. That is the way it is designed to work. Scientific data plots are a special case; in general, when a scene is zoomed, all elements of the scene should also zoom - think of video games, CAD drawings, and things like that.

    As I said, the easiest way for scientific plots or other charts is to implement the part that should zoom separately from the parts that don't, and combine them into a composite widget. I actually use the scale widgets from Qwt for my axes - better than writing all that code from scratch.

  7. #6
    Join Date
    Mar 2013
    Posts
    11
    Thanks
    6
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: How to make some items non movable on scene

    Hi d_stranz,

    Can you please provide me some pointers using QwtscaleWidget along with Qgraphicsview.I tried getting the visible viewport and update axes(no Qwt) based on that but its not accurate every time.I need to update X and Y axis values based on zoom or pan on my plot.

  8. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,321
    Thanks
    316
    Thanked 871 Times in 858 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: How to make some items non movable on scene

    This is the layout of my dataplot widget:

    Dataplot.png

    The DataplotWidget is derived from QWidget, and uses a QLabel for the title, up to 4 QwtScaleWidget instances as top / bottom / left / right axes, and another custom widget derived from QGraphicsView as the "canvas" where the data is displayed.

    The DataplotWidget's showEvent() and resizeEvent() each call a protected method named calculateLayout(). The purpose of this method is to eventually calculate the size and position of the canvas by subtracting out the areas occupied by the other widgets in the Dataplot:


    1. Start with the full DataplotWidget rect
    2. If the title is visible, set its position to the top left and set the top of the canvas rect to the bottom of the title rect
    3. If the top axis is visible, set its top to the bottom of the title. Set the top of the canvas to the bottom of the axis
    4. If the bottom axis is visible, set the bottom of the canvas rect to the top of the bottom axis rect
    5. If the left axis is visible, set its top to the top of the canvas and bottom to the bottom of the canvas. Move the left side of the canvas to the right side of the left axis
    6. If the right axis is visible, set its top and bottom to the canvas top and bottom. Move the right side of the canvas to the left side of the axis
    7. if the top and/or bottom axes are visible, adjust their left and right sides to match the canvas left and right.



    The canvas uses an overlay widget to implement zooming. When the left mouse button is clicked in the canvas, the overlay widget is displayed at the same position and size as the canvas widget, and is used to draw the rubberband. If your canvas contains a very complex scene, then it is best to take a snapshot of the contents (i.e. render the graphics view to a pixmap) and use the pixmap as the background of the overlay window. This allows you to smoothly move the rubberband around without triggering paint events in the graphics view. When the mouse is released, the overlay window is hidden and the canvas widget emits a "zoomed( const QRectF & )" signal, where the coordinates of the QRect are in scene coordinates.

    The DataplotWidget is connected to this signal. When it receives it, it adjusts the axis ranges as appropriate. I have implemented zooming only for the left and bottom axes, but you could extend the behaviour by supporting zoom on any orthogonal pair of axes. If I ever need that, I will have to go back and engineer it in.

    Since each of the sub-widgets is derived from QWidget, they all take care of their own painting. The DataplotWidget itself does not have a paintEvent handler. The canvas uses an external QGraphicsScene, but has its own viewport. This allows the same scene to be displayed on more than one dataplot, with different viewports or level of zoom, and more importantly, without duplicating the underlying data. If you do not need to do this, then you can simply a bit by making the scene a member of the dataplot widget.

    Hope this helps a bit. The actual dataplot I have implemented is much more complex than this. The mouse interactions are implemented in a separate class based on QStateMachine, because it supports about 10 different rubberband modes (horizontal line, vertical line, rectangle, horizontal box, vertical box, lasso, etc.) for zooming, panning, range selection, object selection, and so forth. There is a zoom stack that allows the user to zoom in and then pop out to the previous zoom, etc.

  9. The following user says thank you to d_stranz for this useful post:

    tarunrajsingh (16th April 2013)

  10. #8
    Join Date
    Mar 2013
    Posts
    11
    Thanks
    6
    Qt products
    Qt4 Qt5
    Platforms
    Windows Android

    Default Re: How to make some items non movable on scene

    Thanks a lot d_stranz ,I really appreciate this level of detail and it really helps.My implementation is somewhat like yours except Qwtaxis and State machine for mouse interaction.Keeping a zoom stack is a good idea,I was maintaing in vars which was sort of cumbersome.Another difference is apart from rubber band zoom ,I am also zooming with mouse wheel and I am trying to scale my axis with the same zoom factor but somehow its not proportional,I will try with QwtscaleAxis today....Thanks again for help.

Similar Threads

  1. Replies: 0
    Last Post: 14th February 2012, 11:03
  2. Moving items in a scene via slots
    By ventura8 in forum Qt Programming
    Replies: 2
    Last Post: 30th August 2011, 15:16
  3. add items into scene
    By Noxxik in forum Qt Programming
    Replies: 0
    Last Post: 9th March 2009, 16:32
  4. Can't move Items in the scene
    By maverick_pol in forum Qt Programming
    Replies: 2
    Last Post: 16th May 2008, 09:40
  5. Cann't move movable items on custom graphics view
    By wojtekw in forum Qt Programming
    Replies: 2
    Last Post: 3rd March 2008, 21:30

Tags for this Thread

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
  •  
Qt is a trademark of The Qt Company.