Qt第十八天

Graphics View绘图程序实例

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QMainWindow>
#include<QGraphicsScene>
#include<QLabel>
#include<QGraphicsView>
#include<QTime>
#include<QPointF>
#include<QGraphicsItem>
#include<QFontDialog>
#include<QColorDialog>
#include<QGraphicsItemGroup>
#include<QGraphicsEllipseItem>
#include<QInputDialog>
#include<QGraphicsTextItem>


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 frontZ=0;//用于bring to front
                 //数值越大,越在前面显示
    int backZ=0;//用于bring to back
                //数值越小,越在后面显示
    QGraphicsScene *scene;
    QLabel *labViewCord;//用于记录View坐标
    QLabel *labSceneCord;//用于记录Scene坐标
    QLabel *labItemCord;//用于记录Item坐标
    QLabel *labItemInfo;//用于距离Item信息


public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
    void on_mouseMovePoint(QPoint point);//鼠标移动
    void on_mouseClicked(QPoint point);//鼠标单击
    void on_mouseDoubleClick(QPoint point);//鼠标双击
    void on_keyPress(QKeyEvent *event);//按键事件
    void on_actZoomIn_triggered();


    void on_actZoomOut_triggered();


    void on_actRotateLeft_triggered();


    void on_actRotateRight_triggered();


    void on_actRestore_triggered();


    void on_actEdit_Front_triggered();


    void on_actEdit_Back_triggered();


    void on_actGroup_triggered();


    void on_actGroupBreak_triggered();


    void on_actEdit_Delete_triggered();


    void on_actItem_Ellipse_triggered();


    void on_actItem_Rect_triggered();


    void on_actItem_Circle_triggered();


    void on_actItem_Triangle_triggered();


    void on_actItem_Polygon_triggered();


    void on_actItem_Line_triggered();


    void on_actItem_Text_triggered();


private:
Ui::MainWindow *ui;
};


#endif // MAINWINDOW_H


qwgraphicsview.h

#ifndef QWGRAPHICSVIEW_H
#define QWGRAPHICSVIEW_H
#include <QGraphicsView>
#include<QObject>
#include<QMouseEvent>
#include<QKeyEvent>
#include<QPoint>


class QWGraphicsView : public QGraphicsView
{
    Q_OBJECT


public:
QWGraphicsView(QWidget *parent=nullptr);
protected:
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseDoubleClickEvent(QMouseEvent *event);
    void keyPressEvent(QKeyEvent *event);


signals:
    void mouseMovePoint(QPoint point);//鼠标移动
    void mouseClicked(QPoint point);//鼠标单击
    void mouseDoubleClicked(QPoint point);//鼠标双击
    void keyPress(QKeyEvent *event);//按键事件
};


#endif // QWGRAPHICSVIEW_H


mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//创建状态栏标签
labViewCord=new QLabel("View 坐标:");
labViewCord->setMinimumWidth(150);
ui->statusBar->addWidget(labViewCord);


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);
//创建QGraphicsScene
scene=new QGraphicsScene(-300,-200,600,200);
ui->View->setScene(scene); //与view关联
ui->View->setDragMode(QGraphicsView::RubberBandDrag);//拖放模式,相当于视图选择


ui->View->setCursor(Qt::CrossCursor); //设置鼠标
ui->View->setMouseTracking(true); //窗口部件跟踪鼠标
this->setCentralWidget(ui->View);
//关联
QObject::connect(ui->View,SIGNAL(mouseMovePoint(QPoint)),this, SLOT(on_mouseMovePoint(QPoint)));
QObject::connect(ui->View,SIGNAL(mouseClicked(QPoint)),this, SLOT(on_mouseClicked(QPoint)));
QObject::connect(ui->View,SIGNAL(mouseDoubleClick(QPoint)),this, SLOT(on_mouseDoubleClick(QPoint)));
QObject::connect(ui->View,SIGNAL(keyPress(QKeyEvent*)),this, SLOT(on_keyPress(QKeyEvent*)));


qsrand(QTime::currentTime().second());//随机数初始化
}


MainWindow::~MainWindow()
{
delete ui;
}
/*
 * 这里用一个函数setBrushColor()为3种不同类的对象进行颜色填充
 * setBrushColor()并不是使用了不同类型参数的同名重载函数,
 * 而是在mainwindow.cpp中定义的一个独立模板函数
 * 编译器会自动根据调用setBrushColor的参数的类型生成三个不同参数类型的函数
 */
template<class T> void setBrushColor(T *item)
{//函数模板
    QColor color=item->brush().color();
    color=QColorDialog::getColor(color,nullptr,"选择填充颜色");
    if (color.isValid())
        item->setBrush(QBrush(color));
}
/**
 * @brief MainWindow::on_mouseMovePoint
 * @param point
 */
void MainWindow::on_mouseMovePoint(QPoint point)
{//鼠标移动事件,point是 GraphicsView的坐标,物理坐标
    labViewCord->setText(QString::asprintf("View 坐标:%d,%d",point.x(),point.y()));
    QPointF pointScene=ui->View->mapToScene(point); //转换到Scene坐标
    labSceneCord->setText(QString::asprintf("Scene 坐标:%.0f,%.0f",pointScene.x(),pointScene.y()));
}
/**
 * @brief MainWindow::on_mouseClicked
 * @param point
 */
void MainWindow::on_mouseClicked(QPoint point)
{//鼠标单击事件
    QPointF pointScene=ui->View->mapToScene(point); //转换到Scene坐标
    QGraphicsItem  *item=nullptr;
    item=scene->itemAt(pointScene,ui->View->transform()); //获取光标下的绘图项
    if (item != nullptr) //有绘图项
    {
        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());
    }
}
/**
 * @brief MainWindow::on_mouseDoubleClick
 * @param point
 */
void MainWindow::on_mouseDoubleClick(QPoint point)
{//鼠标双击事件,调用相应的对话框,设置填充颜色、线条颜色或字体
    QPointF pointScene=ui->View->mapToScene(point); //转换到Scene坐标
    QGraphicsItem  *item=nullptr;
    item=scene->itemAt(pointScene,ui->View->transform()); //获取光标下的绘图项
    if (item == nullptr) //没有绘图项
        return;


    switch (item->type())  //绘图项的类型
    { //
    case    QGraphicsRectItem::Type: //矩形框
    { //强制类型转换
        QGraphicsRectItem *theItem=qgraphicsitem_cast<QGraphicsRectItem*>(item);
        setBrushColor(theItem);
        break;
    }
    case    QGraphicsEllipseItem::Type: //椭圆和圆都是 QGraphicsEllipseItem
    {
        QGraphicsEllipseItem *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);
        //        setPenColor(theItem);
        QPen    pen=theItem->pen();
        QColor  color=theItem->pen().color();
        color=QColorDialog::getColor(color,this,"选择线条颜色");
        if (color.isValid())
        {
            pen.setColor(color);
            theItem->setPen(pen);
        }
        break;
    }
    case    QGraphicsTextItem::Type: //文字,设置字体
    {
        QGraphicsTextItem *theItem=qgraphicsitem_cast<QGraphicsTextItem*>(item);
        QFont font=theItem->font();
        bool ok=false;
        font=QFontDialog::getFont(&ok,font,this,"设置字体");
        if (ok)
            theItem->setFont(font);
        break;
    }
    }
}


void MainWindow::on_keyPress(QKeyEvent *event)
{ //按键事件
    if (scene->selectedItems().count()!=1)
        return; //没有选中的绘图项,或选中的多于1个
    QGraphicsItem   *item=scene->selectedItems().at(0);


    if (event->key()==Qt::Key_Delete)//删除
        scene->removeItem(item);
    else if (event->key()==Qt::Key_Space) //顺时针旋转90度
        item->setRotation(90+item->rotation());
    else if (event->key()==Qt::Key_PageUp)//放大
        item->setScale(0.1+item->scale());
    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::on_actZoomIn_triggered()//放大
{
    int cnt=scene->selectedItems().count();
    if(cnt==1)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->setScale(0.1+item->scale());
    }
    else//对View放大
    {
        ui->View->scale(1.1,1.1);
    }
}




void MainWindow::on_actZoomOut_triggered()//缩小
{
    int cnt=scene->selectedItems().count();
    if(cnt==1)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->setScale(item->scale()-0.1);
    }
    else//对View缩小
    {
        ui->View->scale(0.9,0.9);
    }
}




void MainWindow::on_actRotateLeft_triggered()//左旋转
{
    int cnt=scene->selectedItems().count();
    if(cnt==1)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->setRotation(-30+item->rotation());
    }
    else
    {
        ui->View->rotate(-30);
    }
}


void MainWindow::on_actRotateRight_triggered()//右旋转
{
    int cnt=scene->selectedItems().count();
    if(cnt==1)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->setRotation(30+item->rotation());
    }
    else
    {
        ui->View->rotate(30);
    }
}


void MainWindow::on_actRestore_triggered()//恢复
{
    int cnt=scene->selectedItems().count();
    if(cnt==1)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->resetTransform();
    }
    else
    {
        ui->View->resetTransform();
    }
}




void MainWindow::on_actEdit_Front_triggered()//前置
{
    int cnt=scene->selectedItems().count();
    if(cnt>0)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->setZValue(++frontZ);
    }
}


void MainWindow::on_actEdit_Back_triggered()//后置
{
    int cnt=scene->selectedItems().count();
    if(cnt>0)
    {
        QGraphicsItem *item=scene->selectedItems().at(0);
        item->setZValue(--backZ);
    }
}


void MainWindow::on_actGroup_triggered()//组合
{
    int cnt=scene->selectedItems().count();
    if(cnt>1)
    {
        QGraphicsItemGroup *group=new QGraphicsItemGroup;//创建组合
        scene->addItem(group);//添加到场景
        for(int i=0;i<cnt;i++)
        {
            QGraphicsItem *item=scene->selectedItems().at(i);
            item->setSelected(false);//清除选择框
            item->clearFocus();//清除焦点
            group->addToGroup(item);//添加到组合中
        }
        group->setFlags(QGraphicsItem::ItemIsMovable
                        |QGraphicsItem::ItemIsFocusable
                        |QGraphicsItem::ItemIsSelectable);
        group->setZValue(++frontZ);    
        scene->clearSelection();
        group->setSelected(true);
    }
}


void MainWindow::on_actGroupBreak_triggered()//打散
{
    int cnt=scene->selectedItems().count();
    if(cnt>0)
    {
        QGraphicsItemGroup *group;
        group=(QGraphicsItemGroup*)scene->selectedItems().at(0);//这里假设在单击打散按钮时,选中的是一个组合对象,并没有做类型判断
        scene->destroyItemGroup(group);
    }
}


void MainWindow::on_actEdit_Delete_triggered()//删除
{
    int cnt=scene->selectedItems().count();
    if(cnt>0)
    {
        for(int i=0;i<cnt;i++)
        {
        QGraphicsItem *item=scene->selectedItems().at(0);
        scene->removeItem(item);
        }
    }
}


void MainWindow::on_actItem_Ellipse_triggered()//画椭圆
{
    QGraphicsEllipseItem *item=new QGraphicsEllipseItem(-50,-30,100,60);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    item->setBrush(Qt::black);
    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_actItem_Rect_triggered()//画矩形
{
    QGraphicsRectItem *item=new QGraphicsRectItem(-50,-30,100,60);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    item->setBrush(Qt::red);
    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_actItem_Circle_triggered()//画圆形
{
    QGraphicsEllipseItem *item=new QGraphicsEllipseItem(-30,-30,60,60);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    item->setBrush(Qt::green);
    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_actItem_Triangle_triggered()//画三角形
{
    QGraphicsPolygonItem   *item=new QGraphicsPolygonItem;
    QPolygonF   points;
    points.append(QPointF(0,-40));
    points.append(QPointF(60,40));
    points.append(QPointF(-60,40));
    item->setPolygon(points);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    item->setBrush(Qt::yellow);
    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_actItem_Polygon_triggered()//画梯形
{
    QGraphicsPolygonItem   *item=new QGraphicsPolygonItem;
    QPolygonF   points;
    points.append(QPointF(30,-40));
    points.append(QPointF(60,40));
    points.append(QPointF(-60,40));
    points.append(QPointF(-30,-40));
    item->setPolygon(points);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    item->setBrush(Qt::blue);
    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_actItem_Line_triggered()//画直线
{
    QGraphicsLineItem *item=new QGraphicsLineItem(-30,40,30,40);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    QPen pen(Qt::gray);
    item->setPen(pen);
    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_actItem_Text_triggered()//添加文字
{
    QString str=QInputDialog::getText(this,"输入文字","请输入文字");
    QGraphicsTextItem *item=new QGraphicsTextItem(str);
    item->setFlags(QGraphicsItem::ItemIsMovable
                   |QGraphicsItem::ItemIsFocusable
                   |QGraphicsItem::ItemIsSelectable);
    QFont font;
    font.setBold(true);
    font.setWeight(2);
    item->setFont(font);
    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);
}


qwgraphicsview.cpp

#include "qwgraphicsview.h"
#include<QEvent>
#include<QGraphicsView>


/**
 * @brief QWGraphicsView::mouseMoveEvent
 * @param event
 */
void QWGraphicsView::mouseMoveEvent(QMouseEvent *event)//鼠标移动
{


    QPoint point=event->pos();
    emit mouseMovePoint(point);
    QGraphicsView::mouseMoveEvent(event);
}
/**
 * @brief QWGraphicsView::mousePressEvent
 * @param event
 */
void QWGraphicsView::mousePressEvent(QMouseEvent *event)//鼠标单击
{
    if(event->button()==Qt::LeftButton)
    {
        QPoint point=event->pos();
        emit mouseClicked(point);
    }
    QGraphicsView::mousePressEvent(event);
}
/**
 * @brief QWGraphicsView::mouseDoubleClickEvent
 * @param event
 */
void QWGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击
{
    if(event->button()==Qt::LeftButton)
    {
        QPoint point=event->pos();
        emit mouseDoubleClicked(point);
    }
    QGraphicsView::mouseDoubleClickEvent(event);
}
/**
 * @brief QWGraphicsView::keyPressEvent
 * @param event
 */
void QWGraphicsView::keyPressEvent(QKeyEvent *event)//按键事件
{
    emit keyPress(event);
    QGraphicsView::keyPressEvent(event);
}
/**
 * @brief QWGraphicsView::QWGraphicsView
 * @param parent
 */
QWGraphicsView::QWGraphicsView(QWidget *parent):QGraphicsView(parent)
{


}


mainwindow.ui
在这里插入图片描述
运行结果
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/theRookie1/article/details/85044997