PaintView.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. #include "PaintView.h"
  2. #define VIEW_CENTER viewport()->rect().center()
  3. #define VIEW_WIDTH viewport()->rect().width()
  4. #define VIEW_HEIGHT viewport()->rect().height()
  5. PaintView::PaintView(QWidget *parent) :
  6. QGraphicsView(parent)
  7. {
  8. _zoomDelta=0.1; // 缩放的增量
  9. _scaleValue=1.0;
  10. _bMouseTranslate=false;
  11. _translateSpeed=1.0;
  12. this->setRenderHint(QPainter::Antialiasing);
  13. }
  14. PaintView::~PaintView()
  15. {
  16. }
  17. void PaintView::ZoomIn()
  18. {
  19. zoom(1 + _zoomDelta);
  20. }
  21. // 缩小
  22. void PaintView::ZoomOut()
  23. {
  24. zoom(1 - _zoomDelta);
  25. }
  26. void PaintView::zoom(float scaleFactor)
  27. {
  28. // 防止过小或过大
  29. qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
  30. if (factor < 0.07 || factor > 100)
  31. return;
  32. scale(scaleFactor, scaleFactor);
  33. _scaleValue *= scaleFactor;
  34. }
  35. void PaintView::wheelEvent(QWheelEvent *event)
  36. {
  37. // 滚轮的滚动量
  38. QPoint scrollAmount = event->angleDelta();
  39. // 正值表示滚轮远离使用者(放大),负值表示朝向使用者(缩小)
  40. scrollAmount.y() > 0 ? ZoomIn() :ZoomOut();
  41. }
  42. void PaintView::paintEvent(QPaintEvent *event)
  43. {
  44. QGraphicsView::paintEvent(event);
  45. QPainter painter(this->viewport());
  46. painter.setBrush(Qt::gray);
  47. QFont font;
  48. font.setPixelSize(45);
  49. painter.setFont(font);
  50. // painter.drawb(QRectF(width()*0.3,height()*0.2,width()*0.3,height()*0.3),"made by andy!");
  51. }
  52. // 平移
  53. void PaintView::mouseMoveEvent(QMouseEvent *event)
  54. {
  55. if (_bMouseTranslate){
  56. QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(_lastMousePos);
  57. translate(mouseDelta);
  58. }
  59. _lastMousePos = event->pos();
  60. QGraphicsView::mouseMoveEvent(event);
  61. }
  62. void PaintView::mousePressEvent(QMouseEvent *event)
  63. {
  64. if (event->button() == _translateButton) {
  65. // 当光标底下没有 item 时,才能移动
  66. QPointF point = mapToScene(event->pos());
  67. if (scene()->itemAt(point, transform()) == NULL) {
  68. _bMouseTranslate = true;
  69. _lastMousePos = event->pos();
  70. }
  71. }
  72. QGraphicsView::mousePressEvent(event);
  73. }
  74. void PaintView::onAssemblageAction(bool)
  75. {
  76. QList<QGraphicsItem *> selectItems=this->scene()->selectedItems();
  77. QGraphicsItemGroup * groupItems =this->scene()->createItemGroup(selectItems);
  78. QRectF rect =groupItems->boundingRect();
  79. QGraphicsScene *scene =new QGraphicsScene();
  80. scene->setSceneRect(rect);
  81. for(int i=0; i<selectItems.count(); i++)
  82. {
  83. QGraphicsItem *sp = qgraphicsitem_cast<QGraphicsItem*>(selectItems[i]);
  84. scene->addItem(sp);
  85. }
  86. scene->clearSelection();
  87. QImage image(rect.width(),rect.height(),QImage::Format_ARGB32);
  88. image.fill(Qt::transparent);//用透明色填充
  89. QString pngName = "D:/scene44test.png";
  90. QPainter painter(&image);
  91. painter.setRenderHint(QPainter::Antialiasing);
  92. scene->render(&painter);
  93. bool saveSuccess = image.save(pngName);
  94. for(int i=0; i<selectItems.count(); i++)
  95. {
  96. QGraphicsItem *sp = qgraphicsitem_cast<QGraphicsItem*>(selectItems[i]);
  97. this->scene()->addItem(sp);
  98. }
  99. if (!saveSuccess)
  100. {
  101. QMessageBox::about(NULL,"","组合图元失败!");
  102. }
  103. else
  104. QMessageBox::about(NULL,"","组合图元成功!");
  105. SafeDelete(scene);
  106. }
  107. void PaintView::onRotation1Action(bool)
  108. {
  109. QList< QGraphicsItem*> selectItems=this->scene()->selectedItems();
  110. int selectItemsCount =selectItems.count();
  111. for(int i=0; i<selectItemsCount ;i++)
  112. {
  113. //图元自转
  114. QPointF centerPos= selectItems[i]->boundingRect().center() ;
  115. selectItems[i]->setTransformOriginPoint(centerPos);
  116. selectItems[i]->setRotation(selectItems[i]->rotation()+30);
  117. }
  118. }
  119. void PaintView::onRotation2Action(bool)
  120. {
  121. QList<QGraphicsItem *> selectItems=this->scene()->selectedItems();
  122. int selectItemsCount =selectItems.count();
  123. for(int i=0; i<selectItemsCount ;i++)
  124. {
  125. //图元自转
  126. QPointF centerPos= selectItems[i]->boundingRect().center() ;
  127. selectItems[i]->setTransformOriginPoint(centerPos);
  128. selectItems[i]->setRotation(selectItems[i]->rotation()-30);
  129. }
  130. }
  131. void PaintView::onDeleteAction(bool)
  132. {
  133. QList<QGraphicsItem *> selectItems=this->scene()->selectedItems();
  134. int selectItemsCount =selectItems.count();
  135. for(int i=0; i<selectItemsCount ;i++)
  136. {
  137. this->scene()->removeItem(selectItems[i]);
  138. }
  139. }
  140. void PaintView::contextMenuEvent(QContextMenuEvent *event)
  141. {
  142. QList<QGraphicsItem *> selectItems=this->scene()->selectedItems();
  143. int selectItemsCount =selectItems.count();
  144. QMenu menu;
  145. QMimeData * mp = const_cast<QMimeData *>(QApplication::clipboard()->mimeData()) ;
  146. ShapeMimeData * data = dynamic_cast< ShapeMimeData*>( mp );
  147. if ( data ){
  148. QAction * pasteAction = menu.addAction("粘贴图元");
  149. connect(pasteAction,SIGNAL(triggered()),this,SLOT(on_paste));
  150. }
  151. if(selectItemsCount >0)
  152. {
  153. QAction * copyAction = menu.addAction("复制图元(+30)");
  154. connect(copyAction,SIGNAL(triggered()),this,SLOT(on_copy));
  155. QAction * cutAction = menu.addAction("剪切图元");
  156. connect(cutAction,SIGNAL(triggered()),this,SLOT(on_cut));
  157. if(selectItemsCount >1)
  158. {
  159. QAction *assemblageAction = menu.addAction("组合图元");
  160. connect(assemblageAction, SIGNAL(triggered(bool)),
  161. this,SLOT(onAssemblageAction(bool)));
  162. }
  163. QAction * rotation1Action = menu.addAction("旋转图元(+30)");
  164. connect(rotation1Action, SIGNAL(triggered(bool)),
  165. this,SLOT(onRotation1Action(bool)));
  166. QAction *rotation2Action = menu.addAction("旋转图元(-30)");
  167. connect(rotation2Action, SIGNAL(triggered(bool)),
  168. this,SLOT(onRotation2Action(bool)));
  169. QAction *deleteAction = menu.addAction("删除图元");
  170. connect(deleteAction, SIGNAL(triggered(bool)),
  171. this,SLOT(onDeleteAction(bool)));
  172. }
  173. menu.exec(event->globalPos());
  174. }
  175. void PaintView::on_copy()
  176. {
  177. ShapeMimeData * data = new ShapeMimeData( this->scene()->selectedItems() );
  178. QApplication::clipboard()->setMimeData(data);
  179. }
  180. void PaintView::on_paste()
  181. {
  182. }
  183. void PaintView::on_cut()
  184. {
  185. }
  186. void PaintView::mouseReleaseEvent(QMouseEvent *event)
  187. {
  188. if (event->button() == _translateButton)
  189. _bMouseTranslate = false;
  190. QGraphicsView::mouseReleaseEvent(event);
  191. }
  192. void PaintView::resizeEvent(QResizeEvent *event)
  193. {
  194. this->scene()->setSceneRect(this->rect());
  195. }
  196. void PaintView::translate(QPointF delta)
  197. {
  198. // 根据当前 zoom 缩放平移数
  199. delta *= _scaleValue;
  200. delta *= _translateSpeed;
  201. // view 根据鼠标下的点作为锚点来定位 scene
  202. setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
  203. QPoint newCenter(VIEW_WIDTH / 2 - delta.x(), VIEW_HEIGHT / 2 - delta.y());
  204. centerOn(mapToScene(newCenter));
  205. // scene 在 view 的中心点作为锚点
  206. setTransformationAnchor(QGraphicsView::AnchorViewCenter);
  207. }
  208. void PaintView::keyPressEvent(QKeyEvent *event)
  209. {
  210. QList<QGraphicsItem *> selectItems=this->scene()->selectedItems();
  211. int selectItemsCount =selectItems.count();
  212. switch (event->key()) {
  213. case Qt::Key_Up:
  214. if(selectItemsCount==0)
  215. translate(QPointF(0, -2)); // 上移
  216. else
  217. {
  218. for(int i=0; i<selectItemsCount ;i++)
  219. {
  220. selectItems[i]->setPos(selectItems[i]->pos().rx(),selectItems[i]->pos().ry()-1);
  221. }
  222. }
  223. break;
  224. case Qt::Key_Down:
  225. if(selectItemsCount==0)
  226. translate(QPointF(0, 2)); // 下移
  227. else
  228. {
  229. for(int i=0; i<selectItemsCount ;i++)
  230. {
  231. selectItems[i]->setPos(selectItems[i]->pos().rx(),selectItems[i]->pos().ry()+1);
  232. }
  233. }
  234. break;
  235. case Qt::Key_Left:
  236. if(selectItemsCount==0)
  237. translate(QPointF(-2, 0)); // 左移
  238. else
  239. {
  240. for(int i=0; i<selectItemsCount ;i++)
  241. {
  242. selectItems[i]->setPos(selectItems[i]->pos().rx()-1,selectItems[i]->pos().ry());
  243. }
  244. }
  245. break;
  246. case Qt::Key_Right:
  247. if(selectItemsCount==0)
  248. translate(QPointF(2, 0)); // 左移
  249. else
  250. {
  251. for(int i=0; i<selectItemsCount ;i++)
  252. {
  253. selectItems[i]->setPos(selectItems[i]->pos().rx()+1,selectItems[i]->pos().ry());
  254. }
  255. }
  256. break;
  257. case Qt::Key_Plus: // 放大
  258. if(selectItemsCount==0)
  259. ZoomIn();
  260. else
  261. {
  262. for(int i=0; i<selectItemsCount ;i++)
  263. {
  264. qreal scaleSize=selectItems[i]->scale()+0.2;
  265. if(scaleSize>20) scaleSize=20;
  266. QPointF centerPos= selectItems[i]->boundingRect().center() ;
  267. selectItems[i]->setTransformOriginPoint(centerPos);
  268. selectItems[i]->setScale(scaleSize);
  269. }
  270. }
  271. break;
  272. case Qt::Key_Minus: // 缩小
  273. if(selectItemsCount==0)
  274. ZoomOut();
  275. else
  276. {
  277. for(int i=0; i<selectItemsCount ;i++)
  278. {
  279. qreal scaleSize=selectItems[i]->scale()-0.2;
  280. if(scaleSize<0.05) scaleSize=0.05;
  281. QPointF centerPos= selectItems[i]->boundingRect().center() ;
  282. selectItems[i]->setTransformOriginPoint(centerPos);
  283. selectItems[i]->setScale(scaleSize);
  284. }
  285. }
  286. break;
  287. case Qt::Key_Space: // 逆时针旋转
  288. if(selectItemsCount==0)
  289. rotate(-90);
  290. else
  291. {
  292. for(int i=0; i<selectItemsCount ;i++)
  293. {
  294. //图元自转
  295. QPointF centerPos= selectItems[i]->boundingRect().center() ;
  296. selectItems[i]->setTransformOriginPoint(centerPos);
  297. selectItems[i]->setRotation(selectItems[i]->rotation()-1);
  298. }
  299. }
  300. break;
  301. case Qt::Key_Enter: // 顺时针旋转
  302. case Qt::Key_Return:
  303. if(selectItemsCount==0)
  304. rotate(90);
  305. else
  306. {
  307. for(int i=0; i<selectItemsCount ;i++)
  308. {
  309. //图元自转
  310. QPointF centerPos= selectItems[i]->boundingRect().center() ;
  311. selectItems[i]->setTransformOriginPoint(centerPos);
  312. selectItems[i]->setRotation(selectItems[i]->rotation()+1);
  313. }
  314. }
  315. break;
  316. default:
  317. QGraphicsView::keyPressEvent(event);
  318. }
  319. }
  320. void PaintView::SetTranslateSpeed(qreal speed)
  321. {
  322. // 建议速度范围
  323. Q_ASSERT_X(speed >= 0.0 && speed <= 5.0,
  324. "InteractiveView::setTranslateSpeed", "Speed should be in range [0.0,5.0].");
  325. _translateSpeed = speed;
  326. }