Results 1 to 2 of 2

Thread: Custom mouse dragging an entire scene?

  1. #1
    Join Date
    Oct 2009
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default

    Hello, I'm trying to implement dragging in a scene such that all of the images on the scene move exactly the amount that I drag my mouse while the button is pressed. My code for one image worked excellently, but as soon as I went to create an array of images... only one moves, and the one before it periodically "jumps" and all the rest are bumps on a log. How do I get all of them to move?

    Here's the code:

    Qt Code:
    1. #include <QApplication>
    2. #include <QGraphicsEllipseItem>
    3. #include <QGraphicsScene>
    4. #include <QGraphicsView>
    5. #include <QtGui>
    6.  
    7. #include <qdatetime.h>
    8. #include <qmainwindow.h>
    9. #include <qstatusbar.h>
    10. #include <qmessagebox.h>
    11. #include <qmenubar.h>
    12. #include <qapplication.h>
    13. #include <qpainter.h>
    14. #include <qprinter.h>
    15. #include <qlabel.h>
    16. #include <qimage.h>
    17. #include <qpixmap.h>
    18. #include <QMouseEvent>
    19. #include <QStyleOptionGraphicsItem>
    20. #include <qdebug.h>
    21. #include <stdlib.h>
    22. #include <qtimer.h>
    23.  
    24. QString myImgName = "myimg.png";
    25. static QImage *myImg;
    26. int xOffset;
    27. int yOffset;
    28. static const int imageRTTI = 984376;
    29. void debug(QString s)
    30. {
    31. qDebug(s.toAscii());
    32. }
    33.  
    34. class mapScene: public QGraphicsScene
    35. {
    36. public:
    37. mapScene();
    38.  
    39. int mouseMoveX;
    40. int mouseMoveY;
    41. QPointF prevMousePoint;
    42. QPointF currMousePoint;
    43.  
    44. bool mouseDown;
    45. protected:
    46. void mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent );
    47. void mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent );
    48. void mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent );
    49. };
    50.  
    51. mapScene::mapScene()
    52. {
    53. mouseDown = false;
    54. mouseMoveX = 0;
    55. mouseMoveY = 0;
    56. xOffset =0;
    57. yOffset =0;
    58.  
    59. }
    60.  
    61. void mapScene::mouseMoveEvent( QGraphicsSceneMouseEvent * event)
    62. {
    63. if(mouseDown)
    64. {
    65. xOffset = (int)(event->scenePos().x() - event->lastScenePos().x());
    66. yOffset = (int)(event->scenePos().y() - event->lastScenePos().y());
    67. advance();
    68. }
    69. else
    70. {
    71. xOffset = 0;
    72. yOffset = 0;
    73. }
    74. }
    75.  
    76. void mapScene::mousePressEvent( QGraphicsSceneMouseEvent * event)
    77. {
    78. mouseDown = true;
    79. }
    80.  
    81. void mapScene::mouseReleaseEvent( QGraphicsSceneMouseEvent * event)
    82. {
    83. mouseDown = false;
    84. xOffset = 0;
    85. yOffset = 0;
    86. }
    87.  
    88. class ImageItem: public QGraphicsRectItem
    89. {
    90. public:
    91. ImageItem( QImage img );
    92. int rtti () const { return imageRTTI; }
    93. void advance(int phase);
    94. protected:
    95. void paint( QPainter *, const QStyleOptionGraphicsItem *option, QWidget *widget );
    96. private:
    97. QImage image;
    98. QPixmap pixmap;
    99. int state;
    100. };
    101.  
    102.  
    103. void ImageItem::advance(int phase)
    104. {
    105. moveBy(xOffset,yOffset);
    106. xOffset = 0; yOffset = 0;
    107. }
    108.  
    109.  
    110. ImageItem::ImageItem( QImage img )
    111. : image(img)
    112. {
    113. state = 0;
    114. setRect(0, 0, image.width(), image.height());
    115. setFlag(ItemIsMovable);
    116. #if !defined(Q_WS_QWS)
    117. pixmap = pixmap.fromImage(image, Qt::OrderedAlphaDither);
    118. #endif
    119. }
    120.  
    121. void ImageItem::paint( QPainter *p, const QStyleOptionGraphicsItem *option, QWidget * )
    122. {
    123. // On Qt/Embedded, we can paint a QImage as fast as a QPixmap,
    124. // but on other platforms, we need to use a QPixmap.
    125. #if defined(Q_WS_QWS)
    126. p->drawImage( option->exposedRect, image, option->exposedRect, Qt::OrderedAlphaDither );
    127. #else
    128. p->drawPixmap( option->exposedRect, pixmap, option->exposedRect );
    129. #endif
    130. }
    131.  
    132. int main( int argc, char **argv )
    133. {
    134. QApplication app(argc, argv);
    135.  
    136. mapScene scene;//mapScene scene;
    137. scene.setSceneRect( -500.0, -500.0, 1000.0, 1000.0 );//( -100.0, -100.0, 200.0, 200.0 );
    138.  
    139. myImg = new QImage;
    140. myImg->load(myImgName);
    141.  
    142. for (int temp=0;temp<10;temp++)
    143. {
    144. i[temp] = new ImageItem(*myImg);
    145. scene.addItem(i[temp]);
    146. i[temp]->setPos(-200+50*temp,-50);
    147. }
    148.  
    149. QGraphicsView view( &scene );
    150. view.setRenderHints( QPainter::Antialiasing );
    151. view.show();
    152.  
    153. return app.exec();
    154. }
    To copy to clipboard, switch view to plain text mode 

    Here's a youtube video of the program working.

    http://www.youtube.com/watch?v=aqEtnT-TxUo

    Anyone know of a way to embed the video in this thread?

    Oh shoot, I think the advance() function where I put xOffset = 0 and yOffset = 0 is what's causing the images after the first one to not move. I put that in the advance function because I had the issue that the image would keep moving after I stopped the mouse but didn't release the button and it didn't seem that I was able to process a "mouse pressed / held down" event, so by resetting it after the picture was moved, the picture wouldn't move unless the mouse was moved again.

    But now I have multiple images... so, heh. I might need to reset the xOffset and yOffset (Corresponding to the amount the mouse's x and y changed while dragging) after the last image is drawn, but I don't know how to implement that. I could need to pass the x-offset to each image somehow so that all of them could maintain their own x and yoffset variables, and they can all reset their own x and yoffset variables.

    I don't know how to do either of those. Well... let's think. I think I could trigger a variable that signals the first image is being advanced() - when that happens, I can find out how many items are in the scene(can I?), and then count-down for each image whose position has been changed. Once the last one is reached, the count-down reaches zero and then I reset the xOffset and yOffset, and also reset the firstImageBeingAdvanced flag to false (for the next time it gets redrawn).

    Sweet, my idea worked. Now, I'm just getting to be afraid of all the global variables I'm using. Is there a better software practice for sharing values between different classes?

    Qt Code:
    1. #include <QApplication>
    2. #include <QtGui>
    3.  
    4. #include <stdlib.h>
    5. #include <qtimer.h>
    6.  
    7. bool firstOneRedrawn = true;
    8. int numGfxItems = 4;
    9. int redrawnCountDown = 4;
    10.  
    11. QString myImgName = "myimg.png";
    12. static QImage *myImg;
    13.  
    14. int xOffset;
    15. int yOffset;
    16.  
    17. static const int imageRTTI = 984376;
    18.  
    19. void debug(QString s)
    20. {
    21. qDebug(s.toAscii());
    22. }
    23.  
    24. class mapScene: public QGraphicsScene
    25. {
    26. public:
    27. mapScene();
    28.  
    29. int mouseMoveX;
    30. int mouseMoveY;
    31. QPointF prevMousePoint;
    32. QPointF currMousePoint;
    33.  
    34. bool mouseDown;
    35. protected:
    36. void mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent );
    37. void mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent );
    38. void mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent );
    39.  
    40. };
    41.  
    42. mapScene::mapScene()
    43. {
    44. mouseDown = false;
    45. mouseMoveX = 0;
    46. mouseMoveY = 0;
    47. xOffset =0;
    48. yOffset =0;
    49.  
    50. }
    51.  
    52. void mapScene::mouseMoveEvent( QGraphicsSceneMouseEvent * event)
    53. {
    54. if(mouseDown)
    55. {
    56. QString dummy;
    57. debug("mommy");
    58. /*
    59.   debug(dummy.setNum(event->pos().x()));
    60.   debug(dummy.setNum(event->lastPos().x()));
    61.   debug(dummy.setNum(event->lastScenePos().x()));
    62.   debug(dummy.setNum(event->scenePos().x()));
    63.   */
    64. xOffset = (int)(event->scenePos().x() - event->lastScenePos().x());
    65. yOffset = (int)(event->scenePos().y() - event->lastScenePos().y());
    66. numGfxItems = items().count();//gets the amount of items in the scene
    67. advance();
    68. }
    69. else
    70. {
    71. xOffset = 0;
    72. yOffset = 0;
    73. }
    74. }
    75.  
    76. void mapScene::mousePressEvent( QGraphicsSceneMouseEvent * event)
    77. {
    78. mouseDown = true;
    79. }
    80.  
    81. void mapScene::mouseReleaseEvent( QGraphicsSceneMouseEvent * event)
    82. {
    83. mouseDown = false;
    84. xOffset = 0;
    85. yOffset = 0;
    86. }
    87.  
    88.  
    89.  
    90. class ImageItem: public QGraphicsRectItem
    91. {
    92. public:
    93. ImageItem( QImage img );
    94. int rtti () const { return imageRTTI; }
    95. void advance(int phase);
    96. protected:
    97. void paint( QPainter *, const QStyleOptionGraphicsItem *option, QWidget *widget );
    98. private:
    99. QImage image;
    100. QPixmap pixmap;
    101. int state;
    102. };
    103.  
    104.  
    105. void ImageItem::advance(int phase)
    106. {
    107.  
    108. if(firstOneRedrawn)
    109. {
    110. firstOneRedrawn = false;
    111. redrawnCountDown = numGfxItems;
    112. }
    113. redrawnCountDown--;
    114. moveBy(xOffset,yOffset);
    115. if(redrawnCountDown < 1) //resetting the advance function, after all items have been redrawn
    116. {
    117. xOffset = 0; yOffset = 0;
    118. firstOneRedrawn = true;
    119. }
    120. }
    121.  
    122.  
    123. ImageItem::ImageItem( QImage img )
    124. : image(img)
    125. {
    126. state = 0;
    127. setRect(0, 0, image.width(), image.height());
    128. setFlag(ItemIsMovable);
    129. #if !defined(Q_WS_QWS)
    130. pixmap = pixmap.fromImage(image, Qt::OrderedAlphaDither);
    131. #endif
    132. }
    133.  
    134. void ImageItem::paint( QPainter *p, const QStyleOptionGraphicsItem *option, QWidget * )
    135. {
    136. // On Qt/Embedded, we can paint a QImage as fast as a QPixmap,
    137. // but on other platforms, we need to use a QPixmap.
    138. #if defined(Q_WS_QWS)
    139. p->drawImage( option->exposedRect, image, option->exposedRect, Qt::OrderedAlphaDither );
    140. #else
    141. p->drawPixmap( option->exposedRect, pixmap, option->exposedRect );
    142. #endif
    143. }
    144.  
    145. int main( int argc, char **argv )
    146. {
    147.  
    148. QApplication app(argc, argv);
    149.  
    150. mapScene scene;//mapScene scene;
    151. scene.setSceneRect( -500.0, -500.0, 1000.0, 1000.0 );//( -100.0, -100.0, 200.0, 200.0 );
    152.  
    153. myImg = new QImage;
    154. myImg->load(myImgName);
    155.  
    156.  
    157.  
    158. for (int temp=0;temp<10;temp++)
    159. {
    160. i[temp] = new ImageItem(*myImg);
    161. scene.addItem(i[temp]);
    162. i[temp]->setPos(-200+50*temp,-50);
    163. }
    164.  
    165.  
    166.  
    167. QGraphicsView view( &scene );
    168. view.setRenderHints( QPainter::Antialiasing );
    169. view.show();
    170.  
    171. return app.exec();
    172. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by wysota; 26th October 2009 at 09:32. Reason: Please edit your posts instead of writing new ones...

  2. #2
    Join Date
    Oct 2009
    Posts
    23
    Thanked 1 Time in 1 Post
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Custom mouse dragging an entire scene?

    (The below was originally a separate post, if not currently)

    Gotcha.

    (asdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfasdfa sdfasdf need to make sure the post is long enough for the forum software to accept it)
    Last edited by swbluto; 26th October 2009 at 17:02.

Similar Threads

  1. Hover on mouse over while dragging
    By mooreaa in forum Qt Programming
    Replies: 3
    Last Post: 6th February 2010, 11:31
  2. Replies: 9
    Last Post: 26th October 2009, 01:13
  3. Replies: 0
    Last Post: 16th July 2009, 13:44
  4. Dragging mouse selection in QTableWidget
    By yartov in forum Qt Programming
    Replies: 1
    Last Post: 12th April 2008, 16:03

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.