Hello,

I like to implement a magnifying glass like on this web page: http://labs.qt.nokia.com/2009/10/07/magnifying-glass/. This zoom function should work on a qgraphicsview. I read many forums and wikis, but I don't know how to do it. Some people say: use the viewport of the qgraphicsview, others say don't use the paintevent() of the qgraphicsview. But nobody says how to do it.

What I've done so far: creating a class MagnifyingGlas and promoted the class to a qgraphicsview in my mainwindow ui. The qpointer was set on the viewport of the qgraphicsview. But nothing happens.

Qt Code:
  1. /*
  2. magnifyingglas.h
  3. */
  4. #ifndef MAGNIFYINGGLAS_H
  5. #define MAGNIFYINGGLAS_H
  6.  
  7. #include <QWidget>
  8. #include <QGraphicsView>
  9. #include <QBasicTimer>
  10. #include <QImage>
  11. #include <QPixmap>
  12. #include <QPoint>
  13. #include <QGraphicsScene>
  14. #include <QMouseEvent>
  15. #include <QPainter>
  16. #include <QPaintEvent>
  17.  
  18.  
  19. #define HOLD_TIME 71
  20.  
  21. class MagnifyingGlas:public QGraphicsView
  22. {
  23. Q_OBJECT
  24. public:
  25. MagnifyingGlas( QWidget *parent = NULL);
  26.  
  27. void pan(const QPoint &delta);
  28. void activateZoom();
  29.  
  30. protected:
  31. void timerEvent(QTimerEvent *);
  32. void mousePressEvent(QMouseEvent *event);
  33. void mouseMoveEvent(QMouseEvent *event);
  34. void mouseReleaseEvent(QMouseEvent *);
  35. void resizeEvent(QResizeEvent *);
  36. void paintEvent(QPaintEvent *e);
  37. void keyPressEvent(QKeyEvent *event);
  38.  
  39. private:
  40. QImage image;
  41. QPixmap smallPixmap;
  42. QPixmap largePixmap;
  43. QPixmap zoomPixmap;
  44. QPixmap maskPixmap;
  45. bool pressed;
  46. bool snapped;
  47. bool zoomed;
  48. QPoint offset;
  49. QPoint pressPos;
  50. QPoint dragPos;
  51. QBasicTimer tapTimer;
  52. };
  53.  
  54. #endif // MAGNIFYINGGLAS_H
To copy to clipboard, switch view to plain text mode 

Qt Code:
  1. /*
  2. magnifyingglas.cpp
  3. */
  4. #include "magnifyingglas.h"
  5.  
  6. #include <QGraphicsItem>
  7.  
  8. MagnifyingGlas::MagnifyingGlas(QWidget *parent): QGraphicsView(new QGraphicsScene(), parent)
  9. {
  10. pressed = false;
  11. snapped = false;
  12. zoomed = false;
  13.  
  14. image.load("/home/kuehnel/Development/Unbenannt_2.png");
  15. largePixmap.load("/home/kuehnel/Development/Unbenannt_2.png");
  16. smallPixmap = largePixmap.scaled(largePixmap.size()/2);
  17. offset = QPoint(0,0);
  18.  
  19. scene = new QGraphicsScene;
  20. this->setScene(scene);
  21. scene->addPixmap(largePixmap);
  22. }
  23. void MagnifyingGlas::pan(const QPoint &delta)
  24. {
  25. offset += delta;
  26. update();
  27. }
  28.  
  29. void MagnifyingGlas::activateZoom()
  30. {
  31. zoomed = true;
  32. tapTimer.stop();
  33. update();
  34.  
  35. }
  36.  
  37. void MagnifyingGlas::timerEvent(QTimerEvent *)
  38. {
  39. if (!zoomed) activateZoom();
  40. update();
  41. }
  42.  
  43. void MagnifyingGlas::mousePressEvent(QMouseEvent *event)
  44. {
  45. if (event->buttons()!= Qt::LeftButton) return;
  46.  
  47. pressed = snapped = true;
  48. pressPos = dragPos = event->pos();
  49. tapTimer.start(HOLD_TIME, viewport());
  50. }
  51.  
  52. void MagnifyingGlas::mouseMoveEvent(QMouseEvent *event)
  53. {
  54. if (!event->buttons()) return;
  55. if (!zoomed)
  56. {
  57. if (!pressed || !snapped)
  58. {
  59. QPoint delta = event->pos() - pressPos;
  60. pressPos = event->pos();
  61. pan(delta);
  62. return;
  63. }
  64. else
  65. {
  66. const int threshold = 10;
  67. QPoint delta = event->pos() - pressPos;
  68. if (snapped)
  69. {
  70. snapped &= delta.x() < threshold;
  71. snapped &= delta.y() < threshold;
  72. snapped &= delta.x() > -threshold;
  73. snapped &= delta.y() >-threshold;
  74. }
  75. if (!snapped) tapTimer.stop();
  76. }
  77. }
  78. else
  79. {
  80. dragPos = event->pos();
  81. update();
  82. }
  83. }
  84.  
  85. void MagnifyingGlas::mouseReleaseEvent(QMouseEvent *)
  86. {
  87. zoomed = false;
  88. update();
  89. }
  90.  
  91. void MagnifyingGlas::resizeEvent(QResizeEvent *)
  92. {
  93. zoomed = false;
  94. update();
  95. }
  96.  
  97. void MagnifyingGlas::paintEvent(QPaintEvent *e)
  98. {
  99. QPainter p(viewport());
  100. p.drawPixmap(offset,smallPixmap);
  101. p.end();
  102. if (zoomed)
  103. {
  104. int dim = qMin(width(), height());
  105. int magnifierSize = dim * 5/6;
  106. int radius = magnifierSize / 2;
  107. int ring = radius - 15;
  108. QSize box = QSize(magnifierSize, magnifierSize);
  109.  
  110. if(maskPixmap.size() != box)
  111. {
  112. maskPixmap = QPixmap(box);
  113. maskPixmap.fill(Qt::transparent);
  114.  
  115. g.setCenter(radius, radius);
  116. g.setFocalPoint(radius, radius);
  117. g.setRadius(radius);
  118. g.setColorAt(1.0, QColor(64, 64, 64, 0));
  119. g.setColorAt(0.5, QColor(0, 0, 0, 255));
  120.  
  121. QPainter mask(&maskPixmap);
  122. mask.setRenderHint(QPainter::Antialiasing);
  123. mask.setCompositionMode(QPainter::CompositionMode_Source);
  124. mask.setBrush(g);
  125. mask.setPen(Qt::NoPen);
  126. mask.drawRect(maskPixmap.rect());
  127. mask.setBrush(QColor(Qt::transparent));
  128. mask.drawEllipse(g.center(), ring, ring);
  129. mask.end();
  130. }
  131.  
  132. QPoint center = dragPos - QPoint(0, radius);
  133. center = center + QPoint(0, radius/2);
  134. QPoint corner = center - QPoint(radius, radius);
  135. QPoint xy = center * 2 - QPoint(radius, radius);
  136.  
  137.  
  138. if (zoomPixmap.size() != box) zoomPixmap = QPixmap(box);
  139.  
  140. if (true)
  141. {
  142. zoomPixmap.fill(Qt::lightGray);
  143. QPainter p(&zoomPixmap);
  144. p.translate(-xy);
  145. p.drawPixmap(offset * 2, largePixmap);
  146. p.end();
  147. }
  148.  
  149. QPainterPath clipPath;
  150. clipPath.addEllipse(center, ring, ring);
  151.  
  152. QPainter p(viewport());
  153. p.setRenderHint(QPainter::Antialiasing);
  154. p.setClipPath(clipPath);
  155. p.drawPixmap(corner, zoomPixmap);
  156. p.setClipping(false);
  157. p.drawPixmap(corner, maskPixmap);
  158. p.setPen(Qt::gray);
  159. p.drawPath(clipPath);
  160. update();
  161. }
  162. }
  163.  
  164. void MagnifyingGlas::keyPressEvent(QKeyEvent *event)
  165. {
  166. if (!zoomed)
  167. {
  168. if (event->key() == Qt::Key_Left) offset += QPoint(20 , 0);
  169. if (event->key() == Qt::Key_Right) offset += QPoint(-20, 0);
  170. if (event->key() == Qt::Key_Up) offset += QPoint(0 , 20);
  171. if (event->key() == Qt::Key_Down) offset += QPoint(0 , -20);
  172. if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select)
  173. {
  174. dragPos = QPoint(width()/2, height()/2);
  175. activateZoom();
  176. }
  177. update();
  178. }
  179. else
  180. {
  181. if (event->key() == Qt::Key_Z || event->key() == Qt::Key_Select)
  182. {
  183. zoomed = false;
  184. update();
  185. }
  186. QPoint delta(0,0);
  187. if (event->key() == Qt::Key_Left) delta += QPoint(-15, 0);
  188. if (event->key() == Qt::Key_Right) delta += QPoint(15 , 0);
  189. if (event->key() == Qt::Key_Up) delta += QPoint(0 , -15);
  190. if (event->key() == Qt::Key_Down) delta += QPoint(0 , 15);
  191. if (delta != QPoint(0, 0))
  192. {
  193. dragPos += delta;
  194. update();
  195. }
  196. }
  197. }
To copy to clipboard, switch view to plain text mode 

Ideas are welcome.

Greats.