Results 1 to 4 of 4

Thread: Problem with a click-and-drag event, and a question on good practice

  1. #1
    Join Date
    Jul 2014
    Posts
    2
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Question Problem with a click-and-drag event, and a question on good practice

    Hi everyone, this is my first post here, so I apologize if this is the wrong category to be posting in.

    I'm trying to design a node graph editor, similar to those seen in Blender, the Unreal Engine, and Unity. As part of this, I am trying to make a widget extended off of QGraphicsView that, when displayed, a large grid is in the background, and this view can be scrolled by holding down a mouse button and dragging it. However, the code I have right now doesn't work quite right, as the grid doesn't update it's position with the drag offsets.

    NodeGraphWidget.h:
    Qt Code:
    1. #ifndef MAINWINDOW_H
    2. #define MAINWINDOW_H
    3.  
    4. #include <QGraphicsView>
    5. #include <QKeyEvent>
    6. #include <QPoint>
    7.  
    8. class NodeGraphWidget : public QGraphicsView
    9. {
    10. Q_OBJECT
    11.  
    12. public:
    13. NodeGraphWidget(QWidget *parent = 0);
    14.  
    15. public slots:
    16. //void zoomIn();
    17. //void zoomOut();
    18.  
    19. protected:
    20. void keyPressEvent(QKeyEvent *event);
    21. void drawBackground(QPainter *painter, const QRectF &rect);
    22. void mousePressEvent(QMouseEvent *event);
    23. void mouseReleaseEvent(QMouseEvent *event);
    24. void mouseMoveEvent(QMouseEvent *event);
    25.  
    26. float mScale;
    27. int mOffsetX;
    28. int mOffsetY;
    29. bool mMiddleMouseDown;
    30.  
    31. QPoint mOldMousePos, mNewMousePos;
    32. private:
    33. };
    34.  
    35. #endif // MAINWINDOW_H
    To copy to clipboard, switch view to plain text mode 

    NodeGraphWidget.cpp:
    (Note that I purposefully set the offsets to a constant, just to test if the graph would move)
    Qt Code:
    1. #include "NodeGraphWidget.h"
    2.  
    3. #include <QBrush>
    4. #include <QDebug>
    5. #include <QEvent>
    6. #include <QGraphicsScene>
    7. #include <QKeyEvent>
    8.  
    9. NodeGraphWidget::NodeGraphWidget(QWidget *parent)
    10. : QGraphicsView(parent)
    11. {
    12. QGraphicsScene *scene = new QGraphicsScene(this);
    13. scene->setItemIndexMethod(QGraphicsScene::NoIndex);
    14. scene->setSceneRect(0, 0, 400, 400);
    15. setScene(scene);
    16. setViewportUpdateMode(BoundingRectViewportUpdate);
    17. setCacheMode(CacheBackground);
    18. setRenderHint(QPainter::Antialiasing);
    19. setTransformationAnchor(AnchorUnderMouse);
    20. //this->ch
    21. scale(qreal(1.0), qreal(1.0));
    22. //setMinimumSize(400, 400);
    23. setWindowTitle(tr("Test"));
    24.  
    25. mOffsetX = 0;
    26. mOffsetY = 0;
    27. mScale = 1.f;
    28. }
    29.  
    30. void NodeGraphWidget::keyPressEvent(QKeyEvent *event)
    31. {
    32. Q_UNUSED(event);
    33. qDebug() << event->key();
    34. switch(event->key())
    35. {
    36. default: setWindowTitle("FUCK");
    37. }
    38. }
    39.  
    40. void NodeGraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
    41. {
    42. Q_UNUSED(rect);
    43. qDebug() << "redraw bkg, " << mOffsetX << " " << mOffsetY;
    44.  
    45. QRectF sceneRect = this->sceneRect();
    46. painter->setBrush(QBrush(QColor(64,64,64)));
    47. painter->fillRect(sceneRect, Qt::SolidPattern);
    48.  
    49. painter->setPen(QColor(80, 80, 80));
    50. const int gridSize = 150;
    51. for(int y = -3; y < (int)(height()*mScale)%gridSize; y++)
    52. {
    53. for(int x = -3; x < (int)(width()*mScale)%gridSize; x++)
    54. {
    55. painter->drawRect((x*gridSize)-(mOffsetX), (y*gridSize)-(mOffsetY), gridSize, gridSize);
    56. }
    57. }
    58. }
    59.  
    60. void NodeGraphWidget::mousePressEvent(QMouseEvent *event)
    61. {
    62. switch(event->button())
    63. {
    64. case Qt::MiddleButton:
    65. qDebug() << "DOWN";
    66. mMiddleMouseDown = true;
    67. mOldMousePos = event->localPos().toPoint();
    68. break;
    69. }
    70. }
    71.  
    72. void NodeGraphWidget::mouseMoveEvent(QMouseEvent *event)
    73. {
    74. if(mMiddleMouseDown == true)
    75. {
    76. qDebug() << "DRAG";
    77. mNewMousePos = event->localPos().toPoint();
    78. mOffsetX = 75;// mOldMousePos.x() - mNewMousePos.x();
    79. mOffsetY = 75;// mOldMousePos.y() - mNewMousePos.y();
    80. invalidateScene();
    81. }
    82. }
    83.  
    84. void NodeGraphWidget::mouseReleaseEvent(QMouseEvent *event)
    85. {
    86. switch(event->button())
    87. {
    88. case Qt::MiddleButton:
    89. qDebug() << "UP";
    90. mMiddleMouseDown = false;
    91. //mOldMousePos = QPoint(0, 0);
    92. //mNewMousePos = QPoint(0, 0);
    93. mOffsetX = 0;
    94. mOffsetY = 0;
    95. break;
    96. }
    97. }
    To copy to clipboard, switch view to plain text mode 

    At my qDebug() points, the offset variables are indeed being set, it's just when the view is "redrawn" it isn't being offset. Can anybody offer any help on this? I'm totally stumped.

    Which brings me to my next question: is it good practice to have a widget that isn't specified as a scrollable one to be able to do so? I mostly did it so the scrollbars wouldn't show up (and yes, I know that they can be disabled on the scrollable widget classes). It just seemed like a good idea in hindsight. Now that I'm here, however, is this at all good practice? Or should I switch to a scrollable widget to extend off of? Any suggestions would be greatly appreciated, for either of my issues.

    Thanks.

  2. #2
    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: Problem with a click-and-drag event, and a question on good practice

    Basically in drawBackground() all drawing is done in scene coordinates and not in view coordinates and it seems to me you are trying to do it the other way.

    Qt Code:
    1. #include <QtWidgets>
    2.  
    3.  
    4. class GraphicsView : public QGraphicsView {
    5. public:
    6. GraphicsView(QWidget *parent = 0) : QGraphicsView(parent) {
    7. setCacheMode(CacheBackground);
    8. }
    9. protected:
    10. void drawBackground(QPainter *painter, const QRectF &rect) {
    11. const int gridSize = 80;
    12. painter->save();
    13. painter->fillRect(rect, Qt::white);
    14. QPen pen;
    15. pen.setColor(Qt::gray);
    16. pen.setWidth(0);
    17. painter->setPen(pen);
    18. int i = rect.top() / gridSize;
    19. while(i <= rect.bottom()) {
    20. painter->drawLine((int)rect.left(), i, (int)rect.right(), i);
    21. i+=gridSize;
    22. }
    23. i = rect.left() / gridSize;
    24. while(i<= rect.right()) {
    25. painter->drawLine(i, (int)rect.top(), i, (int)rect.bottom());
    26. i+=gridSize;
    27. }
    28.  
    29. painter->restore();
    30.  
    31. }
    32. };
    33.  
    34. int main(int argc, char **argv) {
    35. QApplication app(argc, argv);
    36. GraphicsView view;
    37. view.setScene(new QGraphicsScene(0,0,5000,4000));
    38. view.show();
    39. return app.exec();
    40. }
    To copy to clipboard, switch view to plain text mode 

    BTW. The code posted here has some funny behavior if you scroll the view too fast but you should get the general picture of what I mean.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


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

    Aunvre (29th July 2014)

  4. #3
    Join Date
    Jul 2014
    Posts
    2
    Thanks
    1
    Qt products
    Qt4 Qt5
    Platforms
    Windows

    Default Re: Problem with a click-and-drag event, and a question on good practice

    Thanks wysota, after looking at your example, I picked mine apart and tweaked it some, and now it's working.

    BTW, I just threw in an invalidateScene() call at the start of the drawBackground() and that seemed to fix the weird display problem.

  5. #4
    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: Problem with a click-and-drag event, and a question on good practice

    Quote Originally Posted by Aunvre View Post
    BTW, I just threw in an invalidateScene() call at the start of the drawBackground() and that seemed to fix the weird display problem.
    Bad idea. This way you are redrawing the whole scene (including items). "My" artifacts come most probably from flooring before assignment to "i" variable. They can easily be overcome by assigning 0 instead (with a slight performance penalty).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


Similar Threads

  1. Replies: 1
    Last Post: 22nd April 2013, 17:50
  2. QGraphicsItem right click event problem
    By liqxpil in forum Qt Programming
    Replies: 3
    Last Post: 13th December 2010, 12:54
  3. Replies: 4
    Last Post: 13th May 2009, 17:50
  4. qobject_cast "good coding practice"
    By janus in forum Qt Programming
    Replies: 1
    Last Post: 17th October 2008, 12:02
  5. Mouse click event problem
    By impeteperry in forum Qt Programming
    Replies: 3
    Last Post: 4th April 2007, 13:44

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.