当前位置:   article > 正文

学习笔记 QT之Graphic图形编辑器_qt 图片编辑器 csdn

qt 图片编辑器 csdn

注:本人学习阶段,仅供参考。如有错误,请指正,谢谢!

一、简单介绍GraphicsView框架

        Graphics View框架实现了模型到视图结构的图形管理,能对大量图元进行管理,支持坐标变换和图元组等多种方便的功能。

框架结构三个主要的类:

1)场景类:QGraphicsScene类(管理多个图形项,用于放置图元的容器,但本身不可见)

2)视图类:QGraphicsView类(提供可视窗口,显示场景中的图元,一个场景中有多个视图)

3)图元类:QGraphicsItem类(各个图元的基础类,QT提供了常用图元的标准类)

三元素关系

        QGraphicsItem(图形项) -----addItem()------>QGraphicsScene(图形项的容器,场景)--------setScene()------>QGraphicsView(可视化使场景中的内容)

三元素坐标系

         QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView:: mapFromScene()函数用于视图与场景的坐标进行转换

QT提供常用图元标准类

        当然,也可以在QGraphicsItem类的基础上实现自定义的图元类,即用户可以继承QGraphicsItem实现符合自己需要的图元。

  • QGraphicsLineItem    用来绘制直线,可以通过setLine(const QLineF&)来添加。
  • QGraphicsRectItem    用来绘制矩形,通过setRect()来进行添加
  • QGraphicsEllipseItem    用来绘制椭圆,或者部分椭圆。通过设置setStartAngle(int)和setSpanAngle(int)可以绘制椭圆的一部分。设置的值是1度的1/16。
  • QGraphicsPolygonItem    用来绘制多边形,通过setPolygon()添加
  • QGraphicsPathItem    绘制一个路径,通过setPath()来进行添加
  • QGraphicsSimpleTextItem    绘制简单文本,除了可以设置字体以外,不支持其它的富文本样式
  • QGraphicsTextItem    绘制格式化的文本,可以通过setHtml()或者setDocument()设置html,还可以添加有交互内容的URL超链接。
  • QGraphicsPixmapItem    绘制图片,或者渲染一个图片
  • QGraphicsProxyWidget    绘制任意的QWdiget控件,视图框架允许我们与添加的控件进行交互。

 二、Graphic图形编辑器

        这是一个简单的图形编辑器,它只对视图部分进行了部分重写。添加了各种图元,如圆、椭圆、矩形、文本、图片等,可进行旋转、放大、缩小、前置、后置、组合、散开、删除等功能。

        在代码中有很多地方添加了注释,这里就不一一赘述了。

效果展示:

 源码展示:

ui界面:

mainwindow.h

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QMainWindow>
  4. #include <QGraphicsScene>
  5. #include <QLabel>
  6. namespace Ui {
  7. class MainWindow;
  8. }
  9. class MainWindow : public QMainWindow
  10. {
  11. Q_OBJECT
  12. private:
  13. static const int ItemId = 1; //绘图项自定义数据的key
  14. static const int ItemDesciption = 2;//绘图自定义数据的key
  15. int seqNum = 0;
  16. int backZ = 0;
  17. int frontZ = 0;
  18. // bool isMode = true;
  19. QPoint linePoint;
  20. //直线
  21. bool isline = true;
  22. //矩形
  23. bool isrectangle = true;
  24. //三角形
  25. bool isTriangle = true;
  26. //椭圆
  27. bool isEllipse= true;
  28. QGraphicsScene *scene;
  29. //显示各种坐标
  30. QLabel *labViewCord; //视图
  31. QLabel *labSceneCord; //场景
  32. QLabel *labItemCord; //图元
  33. QLabel *labItemInfo;
  34. QPoint actPoint;
  35. public:
  36. explicit MainWindow(QWidget *parent = 0);
  37. ~MainWindow();
  38. void initview();
  39. void initSlots();
  40. void wheelEvent(QWheelEvent *event); //滑轮
  41. private slots:
  42. void onMouseMovePoint(QPoint ponit); //接收鼠标移动传过来的坐标槽函数
  43. void onMouseClicked(QPoint point); //接收鼠标点击传过来的坐标槽函数
  44. void onMouseRightClicked(QPoint point); //接收鼠标右击传过来的坐标槽函数
  45. void actionTrigger(QAction *act); //菜单槽函数
  46. void onMouseDoubleClick(QPoint point); //接收鼠标双击传过来的坐标槽函数
  47. void onKeyPress(QKeyEvent *event); //接收按键传过来的按键槽函数
  48. //画图的槽函数
  49. void drawPressLine(QPoint point);
  50. void drawReleaseLine(QPoint point);
  51. void onDrawPressRecdangle(QPoint point);
  52. void onDrawReleaseRecdangle(QPoint point);
  53. void drawPressTriangle(QPoint point);
  54. void drawReleaseTriangle(QPoint point);
  55. void drawPressEllipse(QPoint point);
  56. void drawReleaseEllipse(QPoint point);
  57. //各种转到槽
  58. void on_rectangleButton_clicked();
  59. void on_ellipseButton_clicked();
  60. void on_circularButton_clicked();
  61. void on_triangleButton_clicked();
  62. void on_lineButton_clicked();
  63. void on_textButton_clicked();
  64. void on_enlargeButton_clicked();
  65. void on_narrowButton_clicked();
  66. void on_leftButton_clicked();
  67. void on_rightButton_clicked();
  68. void on_frontButton_clicked();
  69. void on_afterButton_clicked();
  70. void on_deleteButton_clicked();
  71. void on_conbButton_clicked();
  72. void on_disperseButton_clicked();
  73. void on_recoveryButton_clicked();
  74. void on_pictrueButton_clicked();
  75. void on_pixmapButton_clicked();
  76. void on_stop_clicked();
  77. void on_run_clicked();
  78. private:
  79. Ui::MainWindow *ui;
  80. };
  81. #endif // MAINWINDOW_H

mainwindow.cpp

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. #include <QGraphicsRectItem>
  4. #include <QInputDialog>
  5. #include <QColorDialog>
  6. #include <QFontDialog>
  7. #include <QTime>
  8. #include <QMenu>
  9. #include <QColor>
  10. #include <QPixmap>
  11. #include <QKeyEvent>
  12. #include <QFileDialog>
  13. #include <QDebug>
  14. template<class T>
  15. void setBrushColor(T *item)
  16. {
  17. //关于更改方块的颜色的模板函数
  18. QColor color = item->brush().color();
  19. color = QColorDialog::getColor(color,NULL,"选择填充颜色");
  20. if(color.isValid()){ //如果存在与此键关联的缓存像素映射,则返回true。否则,如果pixmap被刷新,密钥将不再有效。
  21. item->setBrush(QBrush(color));
  22. }
  23. }
  24. MainWindow::MainWindow(QWidget *parent) :
  25. QMainWindow(parent),
  26. ui(new Ui::MainWindow)
  27. {
  28. ui->setupUi(this);
  29. initview();//美化界面
  30. labViewCord = new QLabel("View 坐标:");
  31. labViewCord->setMinimumWidth(150); //设置最小宽度
  32. ui->statusBar->addWidget(labViewCord);//QStatusBar类提供了一个适合显示状态信息的水平条。
  33. labSceneCord= new QLabel("Scene 坐标:");
  34. labSceneCord->setMinimumWidth(150);
  35. ui->statusBar->addWidget(labSceneCord);
  36. labItemCord = new QLabel("Item 坐标:");
  37. labItemCord->setMinimumWidth(150);
  38. ui->statusBar->addWidget(labItemCord);
  39. labItemInfo = new QLabel("ItemInfo: ");
  40. labItemInfo->setMinimumWidth(200);
  41. ui->statusBar->addWidget(labItemInfo);
  42. scene = new QGraphicsScene(-300, -200, 600, 200);//创建一个场景
  43. ui->graphicsView->setScene(scene); //与view关联
  44. ui->graphicsView->setCursor(Qt::CrossCursor);//设置鼠标,十字光标,通常用于帮助用户准确选择屏幕上的点。
  45. ui->graphicsView->setMouseTracking(true);//启用了鼠标跟踪,即使没有按下按钮,小部件也会接收鼠标移动事件。
  46. //此属性保留按住鼠标左键时在场景上拖动鼠标的行为。
  47. ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);//将出现一条橡皮筋。拖动鼠标将设置橡皮筋几何体,并选择橡皮筋覆盖的所有项目
  48. // this->setCentralWidget(ui->graphicsView); //将给定的小部件设置为主窗口的中心小部件。
  49. initSlots(); //信号与槽
  50. qsrand(QTime::currentTime().second()); //关于线程的一个函数
  51. }
  52. void MainWindow::initview()
  53. {
  54. //保存图片
  55. ui->pictrueButton->setToolTip(QString("保存图片"));
  56. ui->pictrueButton->setIcon(QIcon(":/pictrue/save.png"));
  57. //放大
  58. ui->enlargeButton->setToolTip(QString("放大"));
  59. ui->enlargeButton->setIcon(QIcon(":/pictrue/enlarge.png"));
  60. //缩小
  61. ui->narrowButton->setToolTip(QString("缩小"));
  62. ui->narrowButton->setIcon(QIcon(":/pictrue/narrow.png"));
  63. //左右转
  64. ui->leftButton->setToolTip(QString("左转"));
  65. ui->leftButton->setIcon(QIcon(":/pictrue/rightRotation.png"));
  66. ui->rightButton->setToolTip(QString("右转"));
  67. ui->rightButton->setIcon(QIcon(":/pictrue/leftRotation.png"));
  68. //前面置
  69. ui->frontButton->setToolTip(QString("前置"));
  70. ui->frontButton->setIcon(QIcon(":/pictrue/524.bmp"));
  71. ui->afterButton->setToolTip(QString("后置"));
  72. ui->afterButton->setIcon(QIcon(":/pictrue/522.bmp"));
  73. //恢复
  74. ui->recoveryButton->setToolTip(QString("恢复"));
  75. ui->recoveryButton->setIcon(QIcon(":/pictrue/toFront.png"));
  76. //组合
  77. ui->conbButton->setToolTip(QString("组合"));
  78. ui->conbButton->setIcon(QIcon(":/pictrue/con.png"));
  79. //打散
  80. ui->disperseButton->setToolTip(QString("打散"));
  81. ui->disperseButton->setIcon(QIcon(":/pictrue/dis.png"));
  82. //删除
  83. ui->deleteButton->setToolTip(QString("删除"));
  84. ui->deleteButton->setIcon(QIcon(":/pictrue/108.bmp"));
  85. //图形
  86. ui->circularButton->setIcon(QIcon(":/pictrue/iage/cir.png"));
  87. ui->circularButton->setToolTip(QString("圆形"));
  88. ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell1.png"));
  89. ui->ellipseButton->setToolTip(QString("椭圆"));
  90. ui->lineButton->setIcon(QIcon(":/pictrue/iage/line1.png"));
  91. ui->lineButton->setToolTip(QString("直线"));
  92. ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec1.png"));
  93. ui->rectangleButton->setToolTip(QString("矩形"));
  94. ui->textButton->setIcon(QIcon(":/pictrue/iage/text.bmp"));
  95. ui->textButton->setToolTip(QString("添加文本"));
  96. ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri1.png"));
  97. ui->triangleButton->setToolTip(QString("三角形"));
  98. ui->pixmapButton->setIcon(QIcon(":/pictrue/iage/K1.png"));
  99. ui->pixmapButton->setToolTip(QString("添加图片"));
  100. }
  101. void MainWindow::initSlots() //各种事件的信号与槽
  102. {
  103. connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onMouseClicked(QPoint)));
  104. connect(ui->graphicsView, SIGNAL(mouseRightClicked(QPoint)), this, SLOT(onMouseRightClicked(QPoint)));
  105. connect(ui->graphicsView, SIGNAL(mouseDoubleClick(QPoint)), this, SLOT(onMouseDoubleClick(QPoint)));
  106. connect(ui->graphicsView, SIGNAL(mouseMovePoint(QPoint)), this, SLOT(onMouseMovePoint(QPoint)));
  107. connect(ui->graphicsView, SIGNAL(keyPress(QKeyEvent*)), this, SLOT(onKeyPress(QKeyEvent*)));
  108. connect(ui->preser, SIGNAL(triggered(bool)), this, SLOT(on_pictrueButton_clicked()));
  109. connect(ui->out, SIGNAL(triggered(bool)), this, SLOT(close()));
  110. }
  111. void MainWindow::wheelEvent(QWheelEvent *event) //鼠标滑轮事件
  112. {
  113. if(event->delta() > 0){
  114. on_enlargeButton_clicked();
  115. }else{
  116. on_narrowButton_clicked();
  117. }
  118. }
  119. void MainWindow::onMouseMovePoint(QPoint ponit)//鼠标移动事件,ponit表示view的坐标
  120. {
  121. labViewCord->setText(QString::asprintf("View 坐标:%d,%d", ponit.x(), ponit.y()));
  122. QPointF pointScene = ui->graphicsView->mapToScene(ponit); //转换到Scene坐标
  123. labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(),pointScene.y()));
  124. }
  125. void MainWindow::onMouseClicked(QPoint point)//鼠标左击事件
  126. {
  127. QPointF pointScene = ui->graphicsView->mapToScene(point); //转换到Scene坐标
  128. QGraphicsItem *item = NULL;
  129. item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项
  130. if(item != NULL)
  131. {
  132. QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标
  133. labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y()));
  134. labItemInfo->setText(item->data(ItemDesciption).toString()+", ItemId="+item->data(ItemId).toString());
  135. }
  136. }
  137. void MainWindow::onMouseRightClicked(QPoint point) //鼠标右击出菜单
  138. {
  139. actPoint = point;
  140. QPointF pointScene = ui->graphicsView->mapToScene(point); //转换到scene坐标
  141. QGraphicsItem *item = NULL;
  142. item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项
  143. if(item == NULL) //没有绘图项
  144. {
  145. return;
  146. }
  147. QMenu *menu = new QMenu(this);
  148. menu->addAction(QString("放大"));
  149. menu->addAction(QString("缩小"));
  150. menu->addAction(QString("左转"));
  151. menu->addAction(QString("右转"));
  152. menu->addAction(QString("前置"));
  153. menu->addAction(QString("后置"));
  154. menu->addAction(QString("组合"));
  155. menu->addAction(QString("散开"));
  156. menu->addAction(QString("删除"));
  157. connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(actionTrigger(QAction*)));
  158. menu->exec(QCursor::pos());
  159. }
  160. void MainWindow::actionTrigger(QAction *act)
  161. {
  162. if(act->text() == "放大"){
  163. on_enlargeButton_clicked();
  164. }else if(act->text() == "缩小"){
  165. on_narrowButton_clicked();
  166. }else if(act->text() == "左转"){
  167. on_leftButton_clicked();
  168. }else if(act->text() == "右转"){
  169. on_rightButton_clicked();
  170. }else if(act->text() == "前置"){
  171. on_frontButton_clicked();
  172. }else if(act->text() == "后置"){
  173. on_afterButton_clicked();
  174. }else if(act->text() == "组合"){
  175. on_conbButton_clicked();
  176. }else if(act->text() == "散开"){
  177. on_disperseButton_clicked();
  178. }else if(act->text() == "删除"){
  179. on_deleteButton_clicked();
  180. }
  181. }
  182. void MainWindow::onMouseDoubleClick(QPoint point)//鼠标双击事件,调用相应的对话框,设置填充颜色、字体
  183. {
  184. QPointF pointScene = ui->graphicsView->mapToScene(point);//转换到scene的坐标
  185. QGraphicsItem *item = NULL;
  186. item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项
  187. if(item == NULL) //没有绘图项
  188. {
  189. return;
  190. }
  191. switch(item->type()) //绘图项的类型
  192. {
  193. case QGraphicsRectItem::Type: //矩形框
  194. {
  195. //强制类型转换
  196. QGraphicsRectItem *theItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
  197. setBrushColor(theItem);//更改颜色的模板函数
  198. break;
  199. }
  200. case QGraphicsEllipseItem::Type: //椭圆和圆
  201. {
  202. QGraphicsEllipseItem *theItem;
  203. theItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
  204. setBrushColor(theItem);
  205. break;
  206. }
  207. case QGraphicsPolygonItem::Type: //梯形和三角形
  208. {
  209. QGraphicsPolygonItem *theItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
  210. setBrushColor(theItem);
  211. break;
  212. }
  213. case QGraphicsLineItem::Type: //直线
  214. {
  215. QGraphicsLineItem *theItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
  216. QPen pen = theItem->pen();
  217. QColor color = theItem->pen().color();
  218. color = QColorDialog::getColor(color, this,"选择线条颜色");
  219. if(color.isValid()) //如果颜色有效,则返回true;否则返回false。
  220. {
  221. pen.setColor(color);
  222. theItem->setPen(pen);
  223. }
  224. break;
  225. }
  226. case QGraphicsTextItem::Type: //文字,设置字体
  227. {
  228. QGraphicsTextItem *theItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
  229. QFont font = theItem->font(); //QFont类指定用于绘制文本的字体。
  230. bool ok = false;
  231. font = QFontDialog::getFont(&ok, font, this, "设置字体");
  232. if(ok)
  233. {
  234. theItem->setFont(font);
  235. }
  236. break;
  237. }
  238. }
  239. }
  240. void MainWindow::onKeyPress(QKeyEvent *event)
  241. {
  242. //按键事件
  243. if(scene->selectedItems().count()!=1)//没有选中的绘图项,或选中的多于1个
  244. {
  245. return;
  246. }
  247. QGraphicsItem *item = scene->selectedItems().at(0);
  248. if(event->key() == Qt::Key_Delete){//删除
  249. scene->removeItem(item);
  250. } else if(event->key() == Qt::Key_Space){ //顺时针旋转
  251. item->setRotation(30+item->rotation());//设置围绕Z轴的顺时针旋转角度(以度为单位)。默认值为0
  252. } else if(event->key() == Qt::Key_PageUp){ //放大
  253. item->setScale(0.1+item->scale()); //设置项目的比例因子。默认比例因子为1.0(即,项目未缩放)
  254. } else if(event->key() == Qt::Key_PageDown){ //缩小
  255. item->setScale(-0.1+item->scale());
  256. } else if(event->key() == Qt::Key_Left) { //左移
  257. item->setX(-1+item->x());
  258. } else if(event->key() == Qt::Key_Right){ //右移
  259. item->setX(1+item->x());
  260. } else if(event->key() == Qt::Key_Up){ //上移
  261. item->setY(1+item->y());
  262. } else if(event->key() == Qt::Key_Down){ //下移
  263. item->setY(-1+item->y());
  264. }
  265. }
  266. void MainWindow::drawPressLine(QPoint point)
  267. {
  268. qDebug() << point.x() << point.y();
  269. linePoint = point;
  270. }
  271. void MainWindow::drawReleaseLine(QPoint point) //画直线
  272. {
  273. qDebug() << "画直线";
  274. QGraphicsLineItem *item = new QGraphicsLineItem(0,0,linePoint.x()-point.x(),linePoint.y()-point.y());
  275. item->setFlags(QGraphicsItem::ItemIsMovable
  276. | QGraphicsItem::ItemIsSelectable
  277. | QGraphicsItem::ItemIsFocusable);
  278. QPen pen(Qt::red);
  279. pen.setWidth(3);
  280. item->setPen(pen);
  281. item->setZValue(++frontZ);
  282. QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标
  283. item->setPos(pointScene.x(), pointScene.y());
  284. item->setData(ItemId,++seqNum);
  285. item->setData(ItemDesciption,"直线");
  286. scene->addItem(item);
  287. scene->clearSelection();
  288. item->setSelected(true);
  289. }
  290. void MainWindow::onDrawPressRecdangle(QPoint point)
  291. {
  292. linePoint = point;
  293. }
  294. void MainWindow::onDrawReleaseRecdangle(QPoint point) //画矩形
  295. {
  296. QGraphicsRectItem *item = new QGraphicsRectItem(-abs(linePoint.x()-point.x())/2, -abs(linePoint.y()-point.y())/2, abs(linePoint.x()-point.x()), abs(linePoint.y()-point.y()));//x,y为左上角的图元局部坐标,图元中心为0,0
  297. item->setBrush(QBrush(Qt::yellow)); //设置初始填充颜色
  298. QPointF oldpoint=ui->graphicsView->mapToScene(linePoint); //转换到Scene坐标
  299. QPointF newpoint=ui->graphicsView->mapToScene(point); //转换到Scene坐标
  300. item->setPos((newpoint.x()-oldpoint.x())/2+oldpoint.x(),(newpoint.y()-oldpoint.y())/2+oldpoint.y()); //设置初始坐标
  301. item->setFlags(QGraphicsItem::ItemIsMovable
  302. | QGraphicsItem::ItemIsSelectable
  303. | QGraphicsItem::ItemIsFocusable); //设置图形项的属性,例如:可选择、可移动
  304. item->setZValue(++frontZ);//将项目的Z值设置为Z。Z值决定同级(相邻)项目的堆叠顺序。Z值较高的同级项将始终绘制在Z值较低的另一个同级项的顶部。
  305. //自定义数据
  306. item->setData(ItemId, ++seqNum);
  307. item->setData(ItemDesciption, "矩形");
  308. scene->addItem(item);
  309. // scene->clearSelection(); // 清除当前选择
  310. item->setSelected(true); //初始选择该项目
  311. }
  312. void MainWindow::drawPressTriangle(QPoint point)
  313. {
  314. linePoint = point;
  315. }
  316. void MainWindow::drawReleaseTriangle(QPoint point) //画三角形
  317. {
  318. QGraphicsPolygonItem *item = new QGraphicsPolygonItem;
  319. QPolygonF points; //QPolygonF类使用浮点精度提供点向量。
  320. points.append(QPointF(0,0)); //QPointF类使用浮点精度定义平面中的点。
  321. points.append(QPointF(-((linePoint.x()-point.x())/2),(linePoint.y()-point.y())));
  322. points.append(QPointF((linePoint.x()-point.x())/2,linePoint.y()-point.y()));
  323. item->setPolygon(points);
  324. QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标
  325. item->setPos(pointScene.x()-(point.x()-linePoint.x())/2, pointScene.y());
  326. item->setFlags(QGraphicsItem::ItemIsMovable
  327. | QGraphicsItem::ItemIsSelectable
  328. | QGraphicsItem::ItemIsFocusable);
  329. item->setBrush(QBrush(Qt::magenta));
  330. item->setZValue(++frontZ);
  331. item->setData(ItemId, ++seqNum);
  332. item->setData(ItemDesciption, "三角形");
  333. scene->addItem(item);
  334. scene->clearSelection();
  335. item->setSelected(true);
  336. }
  337. void MainWindow::drawPressEllipse(QPoint point)
  338. {
  339. linePoint = point;
  340. }
  341. void MainWindow::drawReleaseEllipse(QPoint point) //画椭圆
  342. {
  343. QGraphicsEllipseItem *item = new QGraphicsEllipseItem(0, 0, linePoint.x()-point.x(), linePoint.y()-point.y());
  344. item->setFlags(QGraphicsItem::ItemIsMovable
  345. | QGraphicsItem::ItemIsSelectable
  346. | QGraphicsItem::ItemIsFocusable);
  347. item->setBrush(QBrush(Qt::blue));
  348. item->setZValue(++frontZ);
  349. QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标
  350. item->setPos(pointScene.x(), pointScene.y());
  351. item->setData(ItemId, ++seqNum);
  352. item->setData(ItemDesciption, "椭圆");
  353. scene->addItem(item);
  354. scene->clearSelection();
  355. item->setSelected(true);
  356. }
  357. MainWindow::~MainWindow()
  358. {
  359. delete ui;
  360. }
  361. void MainWindow::on_rectangleButton_clicked() //添加矩形
  362. {
  363. if(isrectangle){
  364. connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onDrawPressRecdangle(QPoint)));
  365. connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(onDrawReleaseRecdangle(QPoint)));
  366. ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec.png"));
  367. isrectangle = false;
  368. }else{
  369. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onDrawPressRecdangle(QPoint)));
  370. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(onDrawReleaseRecdangle(QPoint)));
  371. ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec1.png"));
  372. isrectangle = true;
  373. }
  374. qDebug() << isrectangle;
  375. }
  376. void MainWindow::on_ellipseButton_clicked() //添加椭圆
  377. {
  378. if(isEllipse){
  379. connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressEllipse(QPoint)));
  380. connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseEllipse(QPoint)));
  381. ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell.png"));
  382. isEllipse = false;
  383. }else{
  384. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressEllipse(QPoint)));
  385. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseEllipse(QPoint)));
  386. ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell1.png"));
  387. isEllipse = true;
  388. }
  389. }
  390. void MainWindow::on_circularButton_clicked() //添加圆形
  391. {
  392. QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -50, 100, 100);
  393. item->setFlags(QGraphicsItem::ItemIsMovable
  394. | QGraphicsItem::ItemIsSelectable
  395. | QGraphicsItem::ItemIsFocusable);
  396. item->setBrush(QBrush(Qt::cyan)); //青色
  397. item->setZValue(++frontZ);
  398. item->setPos(-50+qrand()%100, -50+(qrand()%100));
  399. item->setData(ItemId, ++seqNum);
  400. item->setData(ItemDesciption, "圆形");
  401. scene->addItem(item);
  402. scene->clearSelection();
  403. item->setSelected(true);
  404. }
  405. void MainWindow::on_triangleButton_clicked() //添加三角形
  406. {
  407. if(isTriangle){
  408. connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressTriangle(QPoint)));
  409. connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseTriangle(QPoint)));
  410. ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri.png"));
  411. isTriangle = false;
  412. }else{
  413. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressTriangle(QPoint)));
  414. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseTriangle(QPoint)));
  415. ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri1.png"));
  416. isTriangle = true;
  417. }
  418. }
  419. void MainWindow::on_lineButton_clicked() //添加直线
  420. {
  421. if(isline){
  422. connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressLine(QPoint)));
  423. connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseLine(QPoint)));
  424. ui->lineButton->setIcon(QIcon(":/pictrue/iage/line.BMP"));
  425. isline = false;
  426. }else{
  427. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressLine(QPoint)));
  428. ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseLine(QPoint)));
  429. ui->lineButton->setIcon(QIcon(":/pictrue/iage/line1.png"));
  430. isline = true;
  431. }
  432. qDebug() << isline;
  433. }
  434. void MainWindow::on_textButton_clicked() //添加文字
  435. {
  436. QString str = QInputDialog::getText(this, "输入文字", "请输入文字");
  437. if(str.isEmpty())
  438. {
  439. return;
  440. }
  441. QGraphicsTextItem *item = new QGraphicsTextItem(str);
  442. QFont font = this->font();
  443. font.setPointSize(20);
  444. font.setBold(true);
  445. item->setFont(font);
  446. item->setFlags(QGraphicsItem::ItemIsMovable
  447. | QGraphicsItem::ItemIsSelectable
  448. | QGraphicsItem::ItemIsFocusable);
  449. item->setPos(-50+(qrand()%100), -50+(qrand()%100));
  450. item->setZValue(++frontZ);
  451. item->setData(ItemId, ++seqNum);
  452. item->setData(ItemDesciption, "文字");
  453. scene->addItem(item);
  454. scene->clearSelection();
  455. item->setSelected(true);
  456. }
  457. void MainWindow::on_enlargeButton_clicked() //放大
  458. {
  459. int cnt = scene->selectedItems().count();
  460. if(cnt == 1){
  461. QGraphicsItem *item;
  462. item = scene->selectedItems().at(0);
  463. item->setScale(0.1+item->scale()); // 比例因子
  464. }else{
  465. ui->graphicsView->scale(1.1,1.1); //按(sx,sy)缩放当前视图变换,正常比例为1,1。
  466. }
  467. }
  468. void MainWindow::on_narrowButton_clicked() //缩小
  469. {
  470. int cnt = scene->selectedItems().count();
  471. if(cnt == 1){
  472. QGraphicsItem *item;
  473. item = scene->selectedItems().at(0);
  474. item->setScale(-0.1+item->scale());
  475. }else{
  476. ui->graphicsView->scale(0.9,0.9); //正常比例为1,1
  477. }
  478. }
  479. void MainWindow::on_leftButton_clicked() //左转
  480. {
  481. int cnt = scene->selectedItems().count();
  482. if(cnt == 1){
  483. QGraphicsItem *item =scene->selectedItems().at(0);
  484. item->setRotation(-30+item->rotation());
  485. }else{
  486. ui->graphicsView->rotate(-30); //rotate:顺时针旋转当前视图变换角度。
  487. }
  488. }
  489. void MainWindow::on_rightButton_clicked() //右转
  490. {
  491. int cnt = scene->selectedItems().count(); //返回所有当前选定项目的列表
  492. if(cnt == 1){
  493. QGraphicsItem *item = scene->selectedItems().at(0);
  494. item->setRotation(30+item->rotation());
  495. }else{
  496. ui->graphicsView->rotate(30);
  497. }
  498. }
  499. void MainWindow::on_frontButton_clicked() //前置
  500. {
  501. int cnt = scene->selectedItems().count();
  502. if(cnt > 0){
  503. //只处理第一个选中项
  504. QGraphicsItem *item = scene->selectedItems().at(0);
  505. item->setZValue(++frontZ);
  506. }
  507. }
  508. void MainWindow::on_afterButton_clicked() //后置
  509. {
  510. int cnt = scene->selectedItems().count();
  511. if(cnt > 0){
  512. QGraphicsItem *item = scene->selectedItems().at(0);
  513. item->setZValue(--backZ);
  514. }
  515. }
  516. void MainWindow::on_deleteButton_clicked() //删除
  517. {
  518. int cnt = scene->selectedItems().count();
  519. if(cnt > 0){
  520. int i = 0;
  521. for(i=0; i < cnt; i++){
  522. QGraphicsItem *item = scene->selectedItems().at(0);
  523. scene->removeItem(item); //删除绘图项
  524. }
  525. }
  526. }
  527. void MainWindow::on_conbButton_clicked() //组合
  528. {
  529. int cnt = scene->selectedItems().count();
  530. if(cnt > 1){
  531. QGraphicsItemGroup *group = new QGraphicsItemGroup;//QGraphicsItemGroup类提供了一个容器,将一组项视为单个项。
  532. // QGraphicsItemGroup是一种特殊类型的复合项,它将自身及其所有子项视为一个项(即,所有子项的所有事件和几何图形都合并在一起)。
  533. scene->addItem(group);
  534. for(int i=0; i<cnt; i++){
  535. QGraphicsItem *item = scene->selectedItems().at(0);
  536. item->setSelected(false);//清除虚线
  537. item->clearFocus(); //
  538. group->addToGroup(item); //添加到组合去
  539. }
  540. group->setFlags(QGraphicsItem::ItemIsMovable
  541. | QGraphicsItem::ItemIsSelectable
  542. | QGraphicsItem::ItemIsFocusable);
  543. group->setZValue(++frontZ);
  544. scene->clearSelection();
  545. group->setSelected(true);
  546. }
  547. }
  548. void MainWindow::on_disperseButton_clicked() //打散
  549. {
  550. int cnt = scene->selectedItems().count();
  551. if(cnt == 1){
  552. QGraphicsItemGroup *group;
  553. group=(QGraphicsItemGroup*)scene->selectedItems().at(0);
  554. scene->destroyItemGroup(group);
  555. //将组中的所有项目重设为组的父项目,然后从场景中移除组,最后将其删除。项目的位置和变换从组映射到组的父对象。
  556. }
  557. }
  558. void MainWindow::on_recoveryButton_clicked() //视图恢复
  559. {
  560. int cnt = scene->selectedItems().count();
  561. if(cnt == 1){
  562. QGraphicsItem *item = scene->selectedItems().at(0);
  563. item->resetTransform();
  564. }else{
  565. ui->graphicsView->resetTransform();//将视图转换重置为标识矩阵。
  566. }
  567. }
  568. void MainWindow::on_pictrueButton_clicked() //保存图片
  569. {
  570. QPixmap map = ui->graphicsView->grab();
  571. QString filename;
  572. filename = QFileDialog::getSaveFileName(this, tr("保存图片"), "", tr("Image Files(*.png *.jpg *.bmp)"));
  573. if(!filename.isNull()){
  574. QFile *file = new QFile(filename);
  575. file->open(QIODevice::ReadWrite);
  576. map.save(file);
  577. file->close();
  578. }
  579. }
  580. void MainWindow::on_pixmapButton_clicked() //添加图片
  581. {
  582. QGraphicsPixmapItem *pixmap = scene->addPixmap(QPixmap(QFileDialog::getOpenFileName(this, "Open", "./", "*.png")));
  583. pixmap->setPos(0,0);
  584. pixmap->setZValue(++frontZ);
  585. pixmap->setFlags(QGraphicsItem::ItemIsMovable
  586. | QGraphicsItem::ItemIsSelectable
  587. | QGraphicsItem::ItemIsFocusable);
  588. pixmap->setData(ItemId, ++seqNum);
  589. pixmap->setData(ItemDesciption, "图片");
  590. scene->addItem(pixmap);
  591. scene->clearSelection();
  592. pixmap->setSelected(true);
  593. }
  594. void MainWindow::on_stop_clicked()
  595. {
  596. int cnt = scene->selectedItems().count();
  597. if(cnt > 0){
  598. int i = 0;
  599. for(i=0; i < cnt; i++){
  600. QGraphicsItem *item = scene->selectedItems().at(i);
  601. item->setFlags(QGraphicsItem::ItemStopsFocusHandling
  602. | QGraphicsItem::ItemIsSelectable);
  603. }
  604. }
  605. }
  606. void MainWindow::on_run_clicked()
  607. {
  608. int cnt = scene->selectedItems().count();
  609. if(cnt > 0){
  610. int i = 0;
  611. for(i=0; i < cnt; i++){
  612. QGraphicsItem *item = scene->selectedItems().at(i);
  613. item->setFlags(QGraphicsItem::ItemIsMovable
  614. | QGraphicsItem::ItemIsSelectable
  615. | QGraphicsItem::ItemIsFocusable);
  616. }
  617. }
  618. }

下面是对视图进行重写,在ui界面对控件进行提升

 mygraphicsview.h

  1. #ifndef MYGRAPHICSVIEW_H
  2. #define MYGRAPHICSVIEW_H
  3. #include <QObject>
  4. #include <QGraphicsView>
  5. class MyGraphicsView : public QGraphicsView
  6. {
  7. Q_OBJECT
  8. public:
  9. MyGraphicsView(QWidget *parent = 0);
  10. QColor BackgroundColor = QColor(53,53,53); //背景颜色
  11. QColor FineGridColor = QColor(0,60,0); //细网格颜色
  12. QColor CoarseGridColor = QColor(120,25,25); //粗网格颜色
  13. protected:
  14. void mouseMoveEvent(QMouseEvent *event); //鼠标移动事件
  15. void mousePressEvent(QMouseEvent *event); //鼠标按下事件
  16. void mouseReleaseEvent(QMouseEvent *event); //鼠标释放事件
  17. void mouseDoubleClickEvent(QMouseEvent *event); //鼠标双击事件
  18. void keyPressEvent(QKeyEvent *event); //键盘按下事件
  19. void drawBackground(QPainter *painter, const QRectF &r); //改变背景颜色
  20. signals:
  21. void mouseMovePoint(QPoint point); //鼠标移动坐标
  22. void mouseClicked(QPoint point); //鼠标左击按下坐标
  23. void mouseRelease(QPoint point); //鼠标释放坐标
  24. void mouseRightClicked(QPoint point);//鼠标右击按下坐标
  25. void mouseDoubleClick(QPoint point); //鼠标双击坐标
  26. void keyPress(QKeyEvent *event); //键盘按下
  27. };
  28. #endif // MYGRAPHICSVIEW_H

mygraphicsview.cpp

  1. #include "mygraphicsview.h"
  2. #include <QMouseEvent>
  3. #include <QPoint>
  4. #include <QRect>
  5. #include <cmath>
  6. MyGraphicsView::MyGraphicsView(QWidget *parent):QGraphicsView(parent)
  7. {
  8. //滚动条隐藏
  9. setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  10. setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
  11. //绘图抗锯齿
  12. setRenderHints(QPainter::Antialiasing);
  13. //设置背景颜色
  14. setBackgroundBrush(BackgroundColor);
  15. }
  16. void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
  17. {
  18. //鼠标移动事件
  19. QPoint point = event->pos(); //保存鼠标移动的坐标
  20. emit mouseMovePoint(point); //发送信号
  21. QGraphicsView::mouseMoveEvent(event); //使父类的事件不受影响
  22. }
  23. void MyGraphicsView::mousePressEvent(QMouseEvent *event)
  24. {
  25. //鼠标按下事件
  26. if(event->button() == Qt::LeftButton) //判断鼠标按下的是左键
  27. {
  28. QPoint point = event->pos(); //保存View此时的坐标
  29. emit mouseClicked(point); //发送信号
  30. }else if(event->button() == Qt::RightButton){ //判断鼠标按下的是右键
  31. QPoint poind = event->pos();
  32. emit mouseRightClicked(poind);
  33. }
  34. QGraphicsView::mousePressEvent(event);
  35. }
  36. void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event)
  37. {
  38. if(event->button() == Qt::LeftButton) //判断鼠标释放的是左键
  39. {
  40. QPoint point = event->pos(); //保存View此时的坐标
  41. emit mouseRelease(point); //发送信号
  42. }
  43. QGraphicsView::mouseReleaseEvent(event);
  44. }
  45. void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
  46. {
  47. //鼠标双击事件
  48. if(event->button() == Qt::LeftButton)
  49. {
  50. QPoint point = event->pos();//保存View此时的坐标
  51. emit mouseDoubleClick(point); //发送信号
  52. }
  53. QGraphicsView::mouseDoubleClickEvent(event);
  54. }
  55. void MyGraphicsView::keyPressEvent(QKeyEvent *event)
  56. {
  57. emit keyPress(event);
  58. QGraphicsView::keyPressEvent(event);
  59. }
  60. void MyGraphicsView::drawBackground(QPainter *painter, const QRectF &r)
  61. {
  62. QGraphicsView::drawBackground(painter, r);
  63. auto drawGrid = [&](double gridStep){
  64. QRect windowRect = rect();
  65. QPointF tl = mapToScene(windowRect.topLeft());
  66. QPointF br = mapToScene(windowRect.bottomRight());
  67. double left = std::floor(tl.x() / gridStep - 0.5);
  68. double right = std::floor(br.x() / gridStep + 1.0);
  69. double bottom = std::floor(tl.y() / gridStep - 0.5);
  70. double top = std::floor(br.y() / gridStep + 1.0);
  71. //垂直线
  72. for(int xi = int(left); xi <= int(right); ++xi){
  73. QLine line(xi * gridStep, bottom * gridStep, xi * gridStep, top * gridStep);
  74. painter->drawLine(line);
  75. }
  76. //水平线
  77. for(int yi = int(bottom); yi<= int(top); ++yi){
  78. QLine line(left * gridStep, yi * gridStep, right * gridStep, yi * gridStep);
  79. painter->drawLine(line);
  80. }
  81. };
  82. QPen pfine(FineGridColor, 1.0);
  83. painter->setPen(pfine);
  84. drawGrid(15);
  85. QPen p(CoarseGridColor, 1.0);
  86. painter->setPen(p);
  87. drawGrid(150);
  88. }

结尾

       这是学习QT之后跟着写的一个小项目,很多地方还有bug,这篇文章只能做一个参考,谢谢!如对你有用,可以点一个小小赞,非常感谢!

       注:如有侵权,请联系本人删除此文章。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/91680
推荐阅读
相关标签
  

闽ICP备14008679号