Results 1 to 5 of 5

Thread: How and/or when to subclass QGraphicsView and QGraphicsScene and properly use them

  1. #1
    Join Date
    Dec 2012
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Symbian S60 Android

    Default How and/or when to subclass QGraphicsView and QGraphicsScene and properly use them

    Have subclassed QGraphicsScene (GridScene) and QGraphicsView (GridView). In GridScene drawBackGround method draw grid with text lables on the hor and ver axis. Must zoom in ,out using QToolButtons, (no scrollbars) on dlg, and pan left, right, up, down with mouse. Cannot get clear view of how to use QGraphicsScene with QGraphicsView.
    1. Do override the mouse events in GridView and GridScene to execute the neccessary actions?
    a. If do What do in the GridView and what in the GridScene methods?
    b. If not, how do propagate the changes to the QGraphicsScene?
    2. When is it necessary to subclass QGraphicsScene, will it be better to draw the grid on the scene in the GridView class?
    3. If also override QGraphicsView:: drawBackGround, what needs to be drawn here and what in GridScene:: drawBackGround ?
    4. Do I need to override paintevent in either or both GridView and GridScene?

    Qt Code:
    1. class GridView : public QGraphicsView
    2. {
    3. Q_OBJECT
    4.  
    5. public:
    6. GridView(QWidget* parent = 0);
    7.  
    8. private:
    9. ...
    10. public slots:
    11. void zoomIn ();
    12. void zoomOut();
    13.  
    14. private:
    15. GridScene* m_scene;
    16. int m_minScaleFactor;
    17. int m_maxScaleFactor;
    18. int m_curScaleFactor;
    19.  
    20. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. GridView::GridView(QWidget* parent)
    2. : QGraphicsView(parent)
    3. {
    4. setGeometry(QRect(0, 0, 474, 621));
    5. setHorizontalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    6. setVerticalScrollBarPolicy (Qt::ScrollBarAlwaysOff);
    7. setDragMode (QGraphicsView::ScrollHandDrag);
    8. m_minScaleFactor = 0;
    9. m_maxScaleFactor = 500;
    10. m_curScaleFactor = 250;
    11. m_curPanX = 0;
    12. m_curPanY = 0;
    13.  
    14. m_scene = new GridScene;
    15. this->setScene (m_scene);
    16. m_scene->setSceneRect(QRectF(0, 0, 1500, 1500));
    17. setBackgroundRole(QPalette::Base);
    18. setAutoFillBackground(true);
    19.  
    20. // setViewportUpdateMode(QGraphicsView::FullViewPortUpdate);
    21. }
    22.  
    23. void GridView::zoomIn ()
    24. {
    25. qreal scale = qPow(qreal(2), (m_curScaleFactor - 250) / qreal(50));
    26. QTransform transform;
    27. transform.scale(scale, scale);
    28. m_curScaleFactor = transform.m11();
    29. }
    30.  
    31. void GridView::mousePressEvent(QMouseEvent *event)
    32. {
    33. if (event->button() == Qt::LeftButton)
    34. {
    35. m_pan = true;
    36. m_panStartX = event->x();
    37. m_panStartY = event->y();
    38. setCursor(Qt::ClosedHandCursor);
    39. event->accept();
    40. return;
    41. }
    42. event->ignore();
    43. }
    44.  
    45. void GridView::mouseMoveEvent(QMouseEvent *event)
    46. {
    47. if (m_pan)
    48. {
    49. m_curPanX = (event->x() - m_panStartX);
    50. m_curPanY = (event->y() - m_panStartY);
    51. m_panStartX = event->x();
    52. m_panStartY = event->y();
    53. event->accept();
    54. return;
    55. }
    56. event->ignore();
    57. }
    58.  
    59. void GridView::mouseReleaseEvent(QMouseEvent *event)
    60. {
    61. if (event->button() == Qt::LeftButton)
    62. {
    63. m_pan = false;
    64. setCursor(Qt::ArrowCursor);
    65.  
    66. m_curPanX = event->x();
    67. m_curPanY = event->y();
    68. setCursor(Qt::OpenHandCursor);
    69. event->accept();
    70. return;
    71. }
    72. event->ignore();
    73. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include <QGraphicsScene>
    2.  
    3. class GridScene : public QGraphicsScene
    4. {
    5.  
    6. public:
    7. GridScene();
    8.  
    9. protected:
    10. void drawBackground(QPainter *painter, const QRectF &rect);
    11.  
    12. private:
    13. ...
    14.  
    15. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. GridScene::GridScene()
    2. {
    3. minX = 0.0;
    4. maxX = 10.0;
    5. numXTicks = 12;
    6.  
    7. minY = 0.0;
    8. maxY = 10.0;
    9. numYTicks = 12;
    10. }
    11.  
    12. void GridScene::drawBackground(QPainter *painter, const QRectF &rect)
    13. {
    14. QRect rect1(Margin, Margin,
    15. width() - 2 * Margin, height() - 2 * Margin);
    16. if (!rect1.isValid())
    17. return;
    18.  
    19. for (int i = 0; i <= numXTicks; ++i) {
    20. int x = rect1.left() + (i * (rect1.width() - 1) / numXTicks);
    21. double label = minX + (i * spanX() / numXTicks);
    22. painter->setPen(QPen(QColor(Qt::darkBlue)));
    23. painter->drawLine(x, rect1.top(), x, rect1.bottom());
    24. painter->setPen(QPen(QColor(Qt::darkBlue)));
    25. painter->drawLine(x, rect1.bottom(), x, rect1.bottom() + 5);
    26. painter->drawText(x - 50, rect1.bottom() + 5, 100, 20,
    27. Qt::AlignHCenter | Qt::AlignTop,
    28. QString::number(label));
    29. }
    30. for (int j = 0; j <= numYTicks; ++j) {
    31. int y = rect1.bottom() - (j * (rect1.height() - 1)/ numYTicks);
    32. double label = minY + (j * spanY()
    33. / numYTicks);
    34. painter->setPen(QPen(QColor(Qt::darkBlue)));
    35. painter->drawLine(rect1.left(), y, rect1.right(), y);
    36. painter->setPen(QPen(QColor(Qt::darkBlue)));
    37. painter->drawLine(rect1.left() - 5, y, rect1.left(), y);
    38. painter->drawText(rect1.left() - Margin, y - 10, Margin - 5, 20,
    39. Qt::AlignRight | Qt::AlignVCenter,
    40. QString::number(label));
    41. }
    42. painter->drawRect(rect1.adjusted(0, 0, -1, -1));
    43. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How and/or when to subclass QGraphicsView and QGraphicsScene and properly use the

    Implement these functions in QGraphicsScene, Grid, Text, X-Axis, Y-Axis, Move items, move text, etc
    Implement these functions in QGraphicsView, Scale/Zoom, Rotation, Shifting, panning, etc
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  3. #3
    Join Date
    Dec 2012
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Symbian S60 Android

    Default Re: How and/or when to subclass QGraphicsView and QGraphicsScene and properly use the

    Thanks. I got the panning to work by first calling the relevant QGraphicsView mouse events first in the overriden functions eg. QGraphicsView::mousePressEvent(event). But zooming still a problem. I can zoom with the mouse wheel (and of course then only up and down)but not by pressing the zoom toolbuttons. In the application zooming with mouse wheel is not allowed but first must get it working properly with the buttons. Do I maybe have to override key pressed events in the view and send a key pressed event from the dialog?

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: How and/or when to subclass QGraphicsView and QGraphicsScene and properly use the

    Create slots in the view to zoom in/out and emit signals from the zoom toolbuttons.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  5. #5
    Join Date
    Dec 2012
    Posts
    3
    Qt products
    Qt4 Qt/Embedded
    Platforms
    Unix/X11 Symbian S60 Android

    Default Re: How and/or when to subclass QGraphicsView and QGraphicsScene and properly use the

    Thank you!
    Got it working, I was trying to be too clever in the zoomIn and -Out methods. A plain call to scale(factor, factor) did it.
    For the next step I may have to start over. The labels for the axis must be visible at all times, so in effect only the grid lines must move on zoom and pan. I've thought about subclassing QGraphicsTextItem for the X and Y labels, and QGraphicsItem for the gird. The current GridScene class then not needed anymore as GridScene::drawBackGround method will be done in the subclassed items, using QGraphicsAnchorLayout to keep the three items in their proper places in the GridView. Not sure how to proceed though. Forward mouse, and button events to the item subclasses? Is this the best way to do it?

Similar Threads

  1. Replies: 1
    Last Post: 1st January 2012, 07:55
  2. Replies: 1
    Last Post: 12th November 2011, 16:40
  3. Replies: 1
    Last Post: 25th October 2010, 13:07
  4. QGraphicsTextItem subclass & QGraphicsScene
    By ttvo in forum Qt Programming
    Replies: 2
    Last Post: 30th August 2009, 15:46
  5. QGraphicsView not updating properly.
    By spraff in forum Qt Programming
    Replies: 0
    Last Post: 3rd July 2009, 10:36

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.