赞
踩
注:本人学习阶段,仅供参考。如有错误,请指正,谢谢!
Graphics View框架实现了模型到视图结构的图形管理,能对大量图元进行管理,支持坐标变换和图元组等多种方便的功能。
框架结构三个主要的类:
1)场景类:QGraphicsScene类(管理多个图形项,用于放置图元的容器,但本身不可见)
2)视图类:QGraphicsView类(提供可视窗口,显示场景中的图元,一个场景中有多个视图)
3)图元类:QGraphicsItem类(各个图元的基础类,QT提供了常用图元的标准类)
三元素关系
QGraphicsItem(图形项) -----addItem()------>QGraphicsScene(图形项的容器,场景)--------setScene()------>QGraphicsView(可视化使场景中的内容)
三元素坐标系
QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView:: mapFromScene()函数用于视图与场景的坐标进行转换
QT提供常用图元标准类
当然,也可以在QGraphicsItem类的基础上实现自定义的图元类,即用户可以继承QGraphicsItem实现符合自己需要的图元。
这是一个简单的图形编辑器,它只对视图部分进行了部分重写。添加了各种图元,如圆、椭圆、矩形、文本、图片等,可进行旋转、放大、缩小、前置、后置、组合、散开、删除等功能。
在代码中有很多地方添加了注释,这里就不一一赘述了。
ui界面:
mainwindow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
-
- #include <QMainWindow>
- #include <QGraphicsScene>
- #include <QLabel>
-
- namespace Ui {
- class MainWindow;
- }
-
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
- private:
- static const int ItemId = 1; //绘图项自定义数据的key
- static const int ItemDesciption = 2;//绘图自定义数据的key
-
- int seqNum = 0;
- int backZ = 0;
- int frontZ = 0;
-
- // bool isMode = true;
- QPoint linePoint;
- //直线
- bool isline = true;
- //矩形
- bool isrectangle = true;
- //三角形
- bool isTriangle = true;
- //椭圆
- bool isEllipse= true;
-
- QGraphicsScene *scene;
- //显示各种坐标
- QLabel *labViewCord; //视图
- QLabel *labSceneCord; //场景
- QLabel *labItemCord; //图元
- QLabel *labItemInfo;
- QPoint actPoint;
-
- public:
- explicit MainWindow(QWidget *parent = 0);
- ~MainWindow();
- void initview();
- void initSlots();
- void wheelEvent(QWheelEvent *event); //滑轮
- private slots:
- void onMouseMovePoint(QPoint ponit); //接收鼠标移动传过来的坐标槽函数
- void onMouseClicked(QPoint point); //接收鼠标点击传过来的坐标槽函数
- void onMouseRightClicked(QPoint point); //接收鼠标右击传过来的坐标槽函数
- void actionTrigger(QAction *act); //菜单槽函数
- void onMouseDoubleClick(QPoint point); //接收鼠标双击传过来的坐标槽函数
- void onKeyPress(QKeyEvent *event); //接收按键传过来的按键槽函数
- //画图的槽函数
- void drawPressLine(QPoint point);
- void drawReleaseLine(QPoint point);
- void onDrawPressRecdangle(QPoint point);
- void onDrawReleaseRecdangle(QPoint point);
- void drawPressTriangle(QPoint point);
- void drawReleaseTriangle(QPoint point);
- void drawPressEllipse(QPoint point);
- void drawReleaseEllipse(QPoint point);
- //各种转到槽
- void on_rectangleButton_clicked();
- void on_ellipseButton_clicked();
- void on_circularButton_clicked();
- void on_triangleButton_clicked();
- void on_lineButton_clicked();
- void on_textButton_clicked();
- void on_enlargeButton_clicked();
- void on_narrowButton_clicked();
- void on_leftButton_clicked();
- void on_rightButton_clicked();
- void on_frontButton_clicked();
- void on_afterButton_clicked();
- void on_deleteButton_clicked();
- void on_conbButton_clicked();
- void on_disperseButton_clicked();
- void on_recoveryButton_clicked();
- void on_pictrueButton_clicked();
- void on_pixmapButton_clicked();
- void on_stop_clicked();
- void on_run_clicked();
-
- private:
- Ui::MainWindow *ui;
- };
-
- #endif // MAINWINDOW_H
mainwindow.cpp
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QGraphicsRectItem>
- #include <QInputDialog>
- #include <QColorDialog>
- #include <QFontDialog>
- #include <QTime>
- #include <QMenu>
- #include <QColor>
- #include <QPixmap>
- #include <QKeyEvent>
- #include <QFileDialog>
- #include <QDebug>
-
- template<class T>
- void setBrushColor(T *item)
- {
- //关于更改方块的颜色的模板函数
- QColor color = item->brush().color();
- color = QColorDialog::getColor(color,NULL,"选择填充颜色");
- if(color.isValid()){ //如果存在与此键关联的缓存像素映射,则返回true。否则,如果pixmap被刷新,密钥将不再有效。
- item->setBrush(QBrush(color));
- }
- }
-
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
-
- initview();//美化界面
-
- labViewCord = new QLabel("View 坐标:");
- labViewCord->setMinimumWidth(150); //设置最小宽度
- ui->statusBar->addWidget(labViewCord);//QStatusBar类提供了一个适合显示状态信息的水平条。
-
- labSceneCord= new QLabel("Scene 坐标:");
- labSceneCord->setMinimumWidth(150);
- ui->statusBar->addWidget(labSceneCord);
-
- labItemCord = new QLabel("Item 坐标:");
- labItemCord->setMinimumWidth(150);
- ui->statusBar->addWidget(labItemCord);
-
- labItemInfo = new QLabel("ItemInfo: ");
- labItemInfo->setMinimumWidth(200);
- ui->statusBar->addWidget(labItemInfo);
-
- scene = new QGraphicsScene(-300, -200, 600, 200);//创建一个场景
-
- ui->graphicsView->setScene(scene); //与view关联
-
- ui->graphicsView->setCursor(Qt::CrossCursor);//设置鼠标,十字光标,通常用于帮助用户准确选择屏幕上的点。
- ui->graphicsView->setMouseTracking(true);//启用了鼠标跟踪,即使没有按下按钮,小部件也会接收鼠标移动事件。
- //此属性保留按住鼠标左键时在场景上拖动鼠标的行为。
- ui->graphicsView->setDragMode(QGraphicsView::RubberBandDrag);//将出现一条橡皮筋。拖动鼠标将设置橡皮筋几何体,并选择橡皮筋覆盖的所有项目
- // this->setCentralWidget(ui->graphicsView); //将给定的小部件设置为主窗口的中心小部件。
- initSlots(); //信号与槽
- qsrand(QTime::currentTime().second()); //关于线程的一个函数
- }
-
- void MainWindow::initview()
- {
- //保存图片
- ui->pictrueButton->setToolTip(QString("保存图片"));
- ui->pictrueButton->setIcon(QIcon(":/pictrue/save.png"));
- //放大
- ui->enlargeButton->setToolTip(QString("放大"));
- ui->enlargeButton->setIcon(QIcon(":/pictrue/enlarge.png"));
- //缩小
- ui->narrowButton->setToolTip(QString("缩小"));
- ui->narrowButton->setIcon(QIcon(":/pictrue/narrow.png"));
- //左右转
- ui->leftButton->setToolTip(QString("左转"));
- ui->leftButton->setIcon(QIcon(":/pictrue/rightRotation.png"));
- ui->rightButton->setToolTip(QString("右转"));
- ui->rightButton->setIcon(QIcon(":/pictrue/leftRotation.png"));
- //前面置
- ui->frontButton->setToolTip(QString("前置"));
- ui->frontButton->setIcon(QIcon(":/pictrue/524.bmp"));
- ui->afterButton->setToolTip(QString("后置"));
- ui->afterButton->setIcon(QIcon(":/pictrue/522.bmp"));
- //恢复
- ui->recoveryButton->setToolTip(QString("恢复"));
- ui->recoveryButton->setIcon(QIcon(":/pictrue/toFront.png"));
- //组合
- ui->conbButton->setToolTip(QString("组合"));
- ui->conbButton->setIcon(QIcon(":/pictrue/con.png"));
- //打散
- ui->disperseButton->setToolTip(QString("打散"));
- ui->disperseButton->setIcon(QIcon(":/pictrue/dis.png"));
- //删除
- ui->deleteButton->setToolTip(QString("删除"));
- ui->deleteButton->setIcon(QIcon(":/pictrue/108.bmp"));
- //图形
- ui->circularButton->setIcon(QIcon(":/pictrue/iage/cir.png"));
- ui->circularButton->setToolTip(QString("圆形"));
- ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell1.png"));
- ui->ellipseButton->setToolTip(QString("椭圆"));
- ui->lineButton->setIcon(QIcon(":/pictrue/iage/line1.png"));
- ui->lineButton->setToolTip(QString("直线"));
- ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec1.png"));
- ui->rectangleButton->setToolTip(QString("矩形"));
- ui->textButton->setIcon(QIcon(":/pictrue/iage/text.bmp"));
- ui->textButton->setToolTip(QString("添加文本"));
- ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri1.png"));
- ui->triangleButton->setToolTip(QString("三角形"));
- ui->pixmapButton->setIcon(QIcon(":/pictrue/iage/K1.png"));
- ui->pixmapButton->setToolTip(QString("添加图片"));
- }
-
- void MainWindow::initSlots() //各种事件的信号与槽
- {
- connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onMouseClicked(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseRightClicked(QPoint)), this, SLOT(onMouseRightClicked(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseDoubleClick(QPoint)), this, SLOT(onMouseDoubleClick(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseMovePoint(QPoint)), this, SLOT(onMouseMovePoint(QPoint)));
- connect(ui->graphicsView, SIGNAL(keyPress(QKeyEvent*)), this, SLOT(onKeyPress(QKeyEvent*)));
- connect(ui->preser, SIGNAL(triggered(bool)), this, SLOT(on_pictrueButton_clicked()));
- connect(ui->out, SIGNAL(triggered(bool)), this, SLOT(close()));
-
- }
-
- void MainWindow::wheelEvent(QWheelEvent *event) //鼠标滑轮事件
- {
- if(event->delta() > 0){
- on_enlargeButton_clicked();
- }else{
- on_narrowButton_clicked();
- }
- }
-
- void MainWindow::onMouseMovePoint(QPoint ponit)//鼠标移动事件,ponit表示view的坐标
- {
- labViewCord->setText(QString::asprintf("View 坐标:%d,%d", ponit.x(), ponit.y()));
- QPointF pointScene = ui->graphicsView->mapToScene(ponit); //转换到Scene坐标
- labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f", pointScene.x(),pointScene.y()));
- }
-
- void MainWindow::onMouseClicked(QPoint point)//鼠标左击事件
- {
- QPointF pointScene = ui->graphicsView->mapToScene(point); //转换到Scene坐标
- QGraphicsItem *item = NULL;
- item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项
- if(item != NULL)
- {
- QPointF pointItem = item->mapFromScene(pointScene); //转换为绘图项的局部坐标
- labItemCord->setText(QString::asprintf("Item 坐标:%.0f,%.0f", pointItem.x(), pointItem.y()));
- labItemInfo->setText(item->data(ItemDesciption).toString()+", ItemId="+item->data(ItemId).toString());
- }
- }
-
- void MainWindow::onMouseRightClicked(QPoint point) //鼠标右击出菜单
- {
- actPoint = point;
- QPointF pointScene = ui->graphicsView->mapToScene(point); //转换到scene坐标
- QGraphicsItem *item = NULL;
- item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项
- if(item == NULL) //没有绘图项
- {
- return;
- }
- QMenu *menu = new QMenu(this);
- menu->addAction(QString("放大"));
- menu->addAction(QString("缩小"));
- menu->addAction(QString("左转"));
- menu->addAction(QString("右转"));
- menu->addAction(QString("前置"));
- menu->addAction(QString("后置"));
- menu->addAction(QString("组合"));
- menu->addAction(QString("散开"));
- menu->addAction(QString("删除"));
- connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(actionTrigger(QAction*)));
- menu->exec(QCursor::pos());
- }
-
- void MainWindow::actionTrigger(QAction *act)
- {
- if(act->text() == "放大"){
- on_enlargeButton_clicked();
- }else if(act->text() == "缩小"){
- on_narrowButton_clicked();
- }else if(act->text() == "左转"){
- on_leftButton_clicked();
- }else if(act->text() == "右转"){
- on_rightButton_clicked();
- }else if(act->text() == "前置"){
- on_frontButton_clicked();
- }else if(act->text() == "后置"){
- on_afterButton_clicked();
- }else if(act->text() == "组合"){
- on_conbButton_clicked();
- }else if(act->text() == "散开"){
- on_disperseButton_clicked();
- }else if(act->text() == "删除"){
- on_deleteButton_clicked();
- }
- }
-
- void MainWindow::onMouseDoubleClick(QPoint point)//鼠标双击事件,调用相应的对话框,设置填充颜色、字体
- {
-
- QPointF pointScene = ui->graphicsView->mapToScene(point);//转换到scene的坐标
- QGraphicsItem *item = NULL;
- item = scene->itemAt(pointScene, ui->graphicsView->transform()); //获取光标下的绘图项
- if(item == NULL) //没有绘图项
- {
- return;
- }
- switch(item->type()) //绘图项的类型
- {
- case QGraphicsRectItem::Type: //矩形框
- {
- //强制类型转换
- QGraphicsRectItem *theItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
- setBrushColor(theItem);//更改颜色的模板函数
- break;
- }
- case QGraphicsEllipseItem::Type: //椭圆和圆
- {
- QGraphicsEllipseItem *theItem;
- theItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
- setBrushColor(theItem);
- break;
- }
- case QGraphicsPolygonItem::Type: //梯形和三角形
- {
- QGraphicsPolygonItem *theItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
- setBrushColor(theItem);
- break;
- }
- case QGraphicsLineItem::Type: //直线
- {
- QGraphicsLineItem *theItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
- QPen pen = theItem->pen();
- QColor color = theItem->pen().color();
- color = QColorDialog::getColor(color, this,"选择线条颜色");
- if(color.isValid()) //如果颜色有效,则返回true;否则返回false。
- {
- pen.setColor(color);
- theItem->setPen(pen);
- }
- break;
- }
- case QGraphicsTextItem::Type: //文字,设置字体
- {
- QGraphicsTextItem *theItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
- QFont font = theItem->font(); //QFont类指定用于绘制文本的字体。
- bool ok = false;
- font = QFontDialog::getFont(&ok, font, this, "设置字体");
- if(ok)
- {
- theItem->setFont(font);
- }
- break;
- }
- }
- }
-
- void MainWindow::onKeyPress(QKeyEvent *event)
- {
- //按键事件
- if(scene->selectedItems().count()!=1)//没有选中的绘图项,或选中的多于1个
- {
- return;
- }
- QGraphicsItem *item = scene->selectedItems().at(0);
-
- if(event->key() == Qt::Key_Delete){//删除
- scene->removeItem(item);
- } else if(event->key() == Qt::Key_Space){ //顺时针旋转
- item->setRotation(30+item->rotation());//设置围绕Z轴的顺时针旋转角度(以度为单位)。默认值为0
- } else if(event->key() == Qt::Key_PageUp){ //放大
- item->setScale(0.1+item->scale()); //设置项目的比例因子。默认比例因子为1.0(即,项目未缩放)
- } else if(event->key() == Qt::Key_PageDown){ //缩小
- item->setScale(-0.1+item->scale());
- } else if(event->key() == Qt::Key_Left) { //左移
- item->setX(-1+item->x());
- } else if(event->key() == Qt::Key_Right){ //右移
- item->setX(1+item->x());
- } else if(event->key() == Qt::Key_Up){ //上移
- item->setY(1+item->y());
- } else if(event->key() == Qt::Key_Down){ //下移
- item->setY(-1+item->y());
- }
- }
-
- void MainWindow::drawPressLine(QPoint point)
- {
- qDebug() << point.x() << point.y();
- linePoint = point;
- }
-
- void MainWindow::drawReleaseLine(QPoint point) //画直线
- {
- qDebug() << "画直线";
- QGraphicsLineItem *item = new QGraphicsLineItem(0,0,linePoint.x()-point.x(),linePoint.y()-point.y());
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
-
- QPen pen(Qt::red);
- pen.setWidth(3);
- item->setPen(pen);
-
- item->setZValue(++frontZ);
- QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标
- item->setPos(pointScene.x(), pointScene.y());
-
- item->setData(ItemId,++seqNum);
- item->setData(ItemDesciption,"直线");
-
- scene->addItem(item);
- scene->clearSelection();
- item->setSelected(true);
-
- }
-
- void MainWindow::onDrawPressRecdangle(QPoint point)
- {
- linePoint = point;
- }
-
- void MainWindow::onDrawReleaseRecdangle(QPoint point) //画矩形
- {
- 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
- item->setBrush(QBrush(Qt::yellow)); //设置初始填充颜色
- QPointF oldpoint=ui->graphicsView->mapToScene(linePoint); //转换到Scene坐标
- QPointF newpoint=ui->graphicsView->mapToScene(point); //转换到Scene坐标
- item->setPos((newpoint.x()-oldpoint.x())/2+oldpoint.x(),(newpoint.y()-oldpoint.y())/2+oldpoint.y()); //设置初始坐标
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable); //设置图形项的属性,例如:可选择、可移动
- item->setZValue(++frontZ);//将项目的Z值设置为Z。Z值决定同级(相邻)项目的堆叠顺序。Z值较高的同级项将始终绘制在Z值较低的另一个同级项的顶部。
-
- //自定义数据
- item->setData(ItemId, ++seqNum);
- item->setData(ItemDesciption, "矩形");
-
- scene->addItem(item);
- // scene->clearSelection(); // 清除当前选择
- item->setSelected(true); //初始选择该项目
-
- }
-
- void MainWindow::drawPressTriangle(QPoint point)
- {
- linePoint = point;
- }
-
- void MainWindow::drawReleaseTriangle(QPoint point) //画三角形
- {
- QGraphicsPolygonItem *item = new QGraphicsPolygonItem;
- QPolygonF points; //QPolygonF类使用浮点精度提供点向量。
- points.append(QPointF(0,0)); //QPointF类使用浮点精度定义平面中的点。
- points.append(QPointF(-((linePoint.x()-point.x())/2),(linePoint.y()-point.y())));
- points.append(QPointF((linePoint.x()-point.x())/2,linePoint.y()-point.y()));
- item->setPolygon(points);
- QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标
- item->setPos(pointScene.x()-(point.x()-linePoint.x())/2, pointScene.y());
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- item->setBrush(QBrush(Qt::magenta));
- item->setZValue(++frontZ);
-
- item->setData(ItemId, ++seqNum);
- item->setData(ItemDesciption, "三角形");
-
- scene->addItem(item);
- scene->clearSelection();
- item->setSelected(true);
- }
-
- void MainWindow::drawPressEllipse(QPoint point)
- {
- linePoint = point;
- }
-
- void MainWindow::drawReleaseEllipse(QPoint point) //画椭圆
- {
- QGraphicsEllipseItem *item = new QGraphicsEllipseItem(0, 0, linePoint.x()-point.x(), linePoint.y()-point.y());
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- item->setBrush(QBrush(Qt::blue));
- item->setZValue(++frontZ);
- QPointF pointScene=ui->graphicsView->mapToScene(point); //转换到Scene坐标
- item->setPos(pointScene.x(), pointScene.y());
-
- item->setData(ItemId, ++seqNum);
- item->setData(ItemDesciption, "椭圆");
-
- scene->addItem(item);
- scene->clearSelection();
- item->setSelected(true);
- }
-
- MainWindow::~MainWindow()
- {
- delete ui;
- }
-
- void MainWindow::on_rectangleButton_clicked() //添加矩形
- {
- if(isrectangle){
- connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onDrawPressRecdangle(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(onDrawReleaseRecdangle(QPoint)));
- ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec.png"));
- isrectangle = false;
- }else{
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(onDrawPressRecdangle(QPoint)));
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(onDrawReleaseRecdangle(QPoint)));
- ui->rectangleButton->setIcon(QIcon(":/pictrue/iage/rec1.png"));
- isrectangle = true;
- }
- qDebug() << isrectangle;
- }
-
- void MainWindow::on_ellipseButton_clicked() //添加椭圆
- {
- if(isEllipse){
- connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressEllipse(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseEllipse(QPoint)));
- ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell.png"));
- isEllipse = false;
- }else{
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressEllipse(QPoint)));
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseEllipse(QPoint)));
- ui->ellipseButton->setIcon(QIcon(":/pictrue/iage/ell1.png"));
- isEllipse = true;
- }
- }
-
- void MainWindow::on_circularButton_clicked() //添加圆形
- {
- QGraphicsEllipseItem *item = new QGraphicsEllipseItem(-50, -50, 100, 100);
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- item->setBrush(QBrush(Qt::cyan)); //青色
- item->setZValue(++frontZ);
- item->setPos(-50+qrand()%100, -50+(qrand()%100));
-
- item->setData(ItemId, ++seqNum);
- item->setData(ItemDesciption, "圆形");
-
- scene->addItem(item);
- scene->clearSelection();
- item->setSelected(true);
- }
-
- void MainWindow::on_triangleButton_clicked() //添加三角形
- {
- if(isTriangle){
- connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressTriangle(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseTriangle(QPoint)));
- ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri.png"));
- isTriangle = false;
- }else{
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressTriangle(QPoint)));
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseTriangle(QPoint)));
- ui->triangleButton->setIcon(QIcon(":/pictrue/iage/tri1.png"));
- isTriangle = true;
- }
-
-
- }
-
- void MainWindow::on_lineButton_clicked() //添加直线
- {
- if(isline){
- connect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressLine(QPoint)));
- connect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseLine(QPoint)));
- ui->lineButton->setIcon(QIcon(":/pictrue/iage/line.BMP"));
- isline = false;
- }else{
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseClicked(QPoint)), this, SLOT(drawPressLine(QPoint)));
- ui->graphicsView->disconnect(ui->graphicsView, SIGNAL(mouseRelease(QPoint)), this, SLOT(drawReleaseLine(QPoint)));
- ui->lineButton->setIcon(QIcon(":/pictrue/iage/line1.png"));
- isline = true;
- }
- qDebug() << isline;
- }
-
- void MainWindow::on_textButton_clicked() //添加文字
- {
- QString str = QInputDialog::getText(this, "输入文字", "请输入文字");
- if(str.isEmpty())
- {
- return;
- }
- QGraphicsTextItem *item = new QGraphicsTextItem(str);
- QFont font = this->font();
- font.setPointSize(20);
- font.setBold(true);
- item->setFont(font);
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- item->setPos(-50+(qrand()%100), -50+(qrand()%100));
- item->setZValue(++frontZ);
-
- item->setData(ItemId, ++seqNum);
- item->setData(ItemDesciption, "文字");
-
- scene->addItem(item);
- scene->clearSelection();
- item->setSelected(true);
- }
-
- void MainWindow::on_enlargeButton_clicked() //放大
- {
- int cnt = scene->selectedItems().count();
- if(cnt == 1){
- QGraphicsItem *item;
- item = scene->selectedItems().at(0);
- item->setScale(0.1+item->scale()); // 比例因子
- }else{
- ui->graphicsView->scale(1.1,1.1); //按(sx,sy)缩放当前视图变换,正常比例为1,1。
- }
- }
-
- void MainWindow::on_narrowButton_clicked() //缩小
- {
- int cnt = scene->selectedItems().count();
- if(cnt == 1){
- QGraphicsItem *item;
- item = scene->selectedItems().at(0);
- item->setScale(-0.1+item->scale());
- }else{
- ui->graphicsView->scale(0.9,0.9); //正常比例为1,1
- }
- }
-
- void MainWindow::on_leftButton_clicked() //左转
- {
- int cnt = scene->selectedItems().count();
- if(cnt == 1){
- QGraphicsItem *item =scene->selectedItems().at(0);
- item->setRotation(-30+item->rotation());
- }else{
- ui->graphicsView->rotate(-30); //rotate:顺时针旋转当前视图变换角度。
- }
- }
-
- void MainWindow::on_rightButton_clicked() //右转
- {
- int cnt = scene->selectedItems().count(); //返回所有当前选定项目的列表
- if(cnt == 1){
- QGraphicsItem *item = scene->selectedItems().at(0);
- item->setRotation(30+item->rotation());
- }else{
- ui->graphicsView->rotate(30);
- }
- }
-
- void MainWindow::on_frontButton_clicked() //前置
- {
- int cnt = scene->selectedItems().count();
- if(cnt > 0){
- //只处理第一个选中项
- QGraphicsItem *item = scene->selectedItems().at(0);
- item->setZValue(++frontZ);
- }
- }
-
- void MainWindow::on_afterButton_clicked() //后置
- {
- int cnt = scene->selectedItems().count();
- if(cnt > 0){
- QGraphicsItem *item = scene->selectedItems().at(0);
- item->setZValue(--backZ);
- }
- }
-
- void MainWindow::on_deleteButton_clicked() //删除
- {
- int cnt = scene->selectedItems().count();
- if(cnt > 0){
- int i = 0;
- for(i=0; i < cnt; i++){
- QGraphicsItem *item = scene->selectedItems().at(0);
- scene->removeItem(item); //删除绘图项
- }
- }
- }
-
- void MainWindow::on_conbButton_clicked() //组合
- {
- int cnt = scene->selectedItems().count();
- if(cnt > 1){
- QGraphicsItemGroup *group = new QGraphicsItemGroup;//QGraphicsItemGroup类提供了一个容器,将一组项视为单个项。
- // QGraphicsItemGroup是一种特殊类型的复合项,它将自身及其所有子项视为一个项(即,所有子项的所有事件和几何图形都合并在一起)。
- scene->addItem(group);
- for(int i=0; i<cnt; i++){
- QGraphicsItem *item = scene->selectedItems().at(0);
- item->setSelected(false);//清除虚线
- item->clearFocus(); //
- group->addToGroup(item); //添加到组合去
- }
- group->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- group->setZValue(++frontZ);
- scene->clearSelection();
- group->setSelected(true);
- }
- }
-
- void MainWindow::on_disperseButton_clicked() //打散
- {
- int cnt = scene->selectedItems().count();
- if(cnt == 1){
- QGraphicsItemGroup *group;
- group=(QGraphicsItemGroup*)scene->selectedItems().at(0);
- scene->destroyItemGroup(group);
- //将组中的所有项目重设为组的父项目,然后从场景中移除组,最后将其删除。项目的位置和变换从组映射到组的父对象。
- }
- }
-
- void MainWindow::on_recoveryButton_clicked() //视图恢复
- {
- int cnt = scene->selectedItems().count();
- if(cnt == 1){
- QGraphicsItem *item = scene->selectedItems().at(0);
- item->resetTransform();
- }else{
- ui->graphicsView->resetTransform();//将视图转换重置为标识矩阵。
- }
- }
-
- void MainWindow::on_pictrueButton_clicked() //保存图片
- {
- QPixmap map = ui->graphicsView->grab();
- QString filename;
- filename = QFileDialog::getSaveFileName(this, tr("保存图片"), "", tr("Image Files(*.png *.jpg *.bmp)"));
- if(!filename.isNull()){
- QFile *file = new QFile(filename);
- file->open(QIODevice::ReadWrite);
- map.save(file);
- file->close();
- }
- }
-
- void MainWindow::on_pixmapButton_clicked() //添加图片
- {
- QGraphicsPixmapItem *pixmap = scene->addPixmap(QPixmap(QFileDialog::getOpenFileName(this, "Open", "./", "*.png")));
- pixmap->setPos(0,0);
- pixmap->setZValue(++frontZ);
- pixmap->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- pixmap->setData(ItemId, ++seqNum);
- pixmap->setData(ItemDesciption, "图片");
-
- scene->addItem(pixmap);
- scene->clearSelection();
- pixmap->setSelected(true);
- }
-
- void MainWindow::on_stop_clicked()
- {
- int cnt = scene->selectedItems().count();
- if(cnt > 0){
- int i = 0;
- for(i=0; i < cnt; i++){
- QGraphicsItem *item = scene->selectedItems().at(i);
- item->setFlags(QGraphicsItem::ItemStopsFocusHandling
- | QGraphicsItem::ItemIsSelectable);
- }
- }
- }
-
- void MainWindow::on_run_clicked()
- {
- int cnt = scene->selectedItems().count();
- if(cnt > 0){
- int i = 0;
- for(i=0; i < cnt; i++){
- QGraphicsItem *item = scene->selectedItems().at(i);
- item->setFlags(QGraphicsItem::ItemIsMovable
- | QGraphicsItem::ItemIsSelectable
- | QGraphicsItem::ItemIsFocusable);
- }
- }
- }
-
下面是对视图进行重写,在ui界面对控件进行提升
mygraphicsview.h
- #ifndef MYGRAPHICSVIEW_H
- #define MYGRAPHICSVIEW_H
-
- #include <QObject>
- #include <QGraphicsView>
-
- class MyGraphicsView : public QGraphicsView
- {
- Q_OBJECT
- public:
- MyGraphicsView(QWidget *parent = 0);
-
-
- QColor BackgroundColor = QColor(53,53,53); //背景颜色
- QColor FineGridColor = QColor(0,60,0); //细网格颜色
- QColor CoarseGridColor = QColor(120,25,25); //粗网格颜色
-
- protected:
- void mouseMoveEvent(QMouseEvent *event); //鼠标移动事件
- void mousePressEvent(QMouseEvent *event); //鼠标按下事件
- void mouseReleaseEvent(QMouseEvent *event); //鼠标释放事件
- void mouseDoubleClickEvent(QMouseEvent *event); //鼠标双击事件
- void keyPressEvent(QKeyEvent *event); //键盘按下事件
- void drawBackground(QPainter *painter, const QRectF &r); //改变背景颜色
- signals:
- void mouseMovePoint(QPoint point); //鼠标移动坐标
- void mouseClicked(QPoint point); //鼠标左击按下坐标
- void mouseRelease(QPoint point); //鼠标释放坐标
- void mouseRightClicked(QPoint point);//鼠标右击按下坐标
- void mouseDoubleClick(QPoint point); //鼠标双击坐标
- void keyPress(QKeyEvent *event); //键盘按下
- };
-
- #endif // MYGRAPHICSVIEW_H
mygraphicsview.cpp
- #include "mygraphicsview.h"
- #include <QMouseEvent>
- #include <QPoint>
- #include <QRect>
- #include <cmath>
-
- MyGraphicsView::MyGraphicsView(QWidget *parent):QGraphicsView(parent)
- {
- //滚动条隐藏
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- //绘图抗锯齿
- setRenderHints(QPainter::Antialiasing);
- //设置背景颜色
- setBackgroundBrush(BackgroundColor);
- }
-
- void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
- {
- //鼠标移动事件
- QPoint point = event->pos(); //保存鼠标移动的坐标
- emit mouseMovePoint(point); //发送信号
- QGraphicsView::mouseMoveEvent(event); //使父类的事件不受影响
- }
-
- void MyGraphicsView::mousePressEvent(QMouseEvent *event)
- {
- //鼠标按下事件
- if(event->button() == Qt::LeftButton) //判断鼠标按下的是左键
- {
- QPoint point = event->pos(); //保存View此时的坐标
- emit mouseClicked(point); //发送信号
- }else if(event->button() == Qt::RightButton){ //判断鼠标按下的是右键
- QPoint poind = event->pos();
- emit mouseRightClicked(poind);
- }
- QGraphicsView::mousePressEvent(event);
- }
-
- void MyGraphicsView::mouseReleaseEvent(QMouseEvent *event)
- {
- if(event->button() == Qt::LeftButton) //判断鼠标释放的是左键
- {
- QPoint point = event->pos(); //保存View此时的坐标
- emit mouseRelease(point); //发送信号
- }
- QGraphicsView::mouseReleaseEvent(event);
- }
-
- void MyGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
- {
- //鼠标双击事件
- if(event->button() == Qt::LeftButton)
- {
- QPoint point = event->pos();//保存View此时的坐标
- emit mouseDoubleClick(point); //发送信号
- }
- QGraphicsView::mouseDoubleClickEvent(event);
- }
-
- void MyGraphicsView::keyPressEvent(QKeyEvent *event)
- {
- emit keyPress(event);
- QGraphicsView::keyPressEvent(event);
- }
-
- void MyGraphicsView::drawBackground(QPainter *painter, const QRectF &r)
- {
- QGraphicsView::drawBackground(painter, r);
- auto drawGrid = [&](double gridStep){
- QRect windowRect = rect();
- QPointF tl = mapToScene(windowRect.topLeft());
- QPointF br = mapToScene(windowRect.bottomRight());
- double left = std::floor(tl.x() / gridStep - 0.5);
- double right = std::floor(br.x() / gridStep + 1.0);
- double bottom = std::floor(tl.y() / gridStep - 0.5);
- double top = std::floor(br.y() / gridStep + 1.0);
- //垂直线
- for(int xi = int(left); xi <= int(right); ++xi){
- QLine line(xi * gridStep, bottom * gridStep, xi * gridStep, top * gridStep);
- painter->drawLine(line);
- }
- //水平线
- for(int yi = int(bottom); yi<= int(top); ++yi){
- QLine line(left * gridStep, yi * gridStep, right * gridStep, yi * gridStep);
- painter->drawLine(line);
- }
- };
- QPen pfine(FineGridColor, 1.0);
- painter->setPen(pfine);
- drawGrid(15);
- QPen p(CoarseGridColor, 1.0);
- painter->setPen(p);
- drawGrid(150);
- }
这是学习QT之后跟着写的一个小项目,很多地方还有bug,这篇文章只能做一个参考,谢谢!如对你有用,可以点一个小小赞,非常感谢!
注:如有侵权,请联系本人删除此文章。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。