源码下载地址:(https://download.csdn.net/download/qq_42503022/14156705
实现在桌面上画图,截图 ,和颜色选择 ,马赛克 撤销回退
绘图使用 QGraphicsView 显示 ,QGraphicsScene 绘图的场景 ,撤销 恢复 使用 QUndoCommand QUndoStack
一下是部分代码展示,需要源码联系我,本人菜鸟大神勿喷!!
#ifndef CANVASSCENE_H
#define CANVASSCENE_H
#include <QGraphicsScene>
#include "textitem.h"
#include "eraser.h"
enum BrushState {
BRUSH_ENUM,
RECT_ENUM,
LINE_ENUM,
ROUND_ENUM,
ARROW_ENUM,
TEXT_ENUM,
MOSAIC_ENUM
};
struct RectAndColor{
QRect rect;
QColor color;
bool bIsFuzzy;//是否已经模糊区域
};
class CanvasScene:public QGraphicsScene
{
Q_OBJECT
public:
CanvasScene();
void setBrushState(BrushState brush);
void setLineWidth(int nLineWidth);
void calculateRectAndColor();
protected:
void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) override;
signals :
void addItemSignal(BrushState brush,QGraphicsItem *item);
void toolbarTopSignal();
public slots:
void onSetColor(QString color);
void editorLostFocus(TextItem *item);
void itemSelected(QGraphicsItem *item);
private:
int m_brushState;
QPointF m_curPoint;
QPointF m_prevPoint;
QColor m_color;
int m_nPenWidth;
QPainterPath m_linePath;
QGraphicsPathItem * m_linePathItem;
QGraphicsPathItem * m_pathItem;
QGraphicsLineItem *m_lineItem;
QGraphicsRectItem *m_rectItem;
QGraphicsEllipseItem *m_ellipseItem;
QGraphicsPolygonItem *m_polygItem;
TextItem *m_textItem;
// Eraser *m_eraser;
bool m_bIsMousePress;
bool m_bIsAddText;
QImage m_image;
QColor m_mosColor;
// QMap<QRect,QColor> m_rectMap;
QVector<RectAndColor> m_vRectAndColor;
};
#endif // CANVASSCENE_H
#include "canvasscene.h"
#include <QGraphicsSceneMouseEvent>
#include <QTextCursor>
#include <QtMath>
#include <QDebug>
#include "selectcolorwnd.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QScreen>
#include <QPixmap>
#include <QGraphicsEffect>
CanvasScene::CanvasScene():
m_brushState(-1),
m_color(Qt::black),
m_nPenWidth(2),
m_linePathItem(nullptr),
m_pathItem(nullptr),
m_lineItem(nullptr),
m_rectItem(nullptr),
m_ellipseItem(nullptr),
m_polygItem(nullptr),
m_textItem(nullptr),
//m_eraser(nullptr),
m_bIsMousePress(false),
m_bIsAddText(true)
{
connect(SelectColorWnd::getInstance(),&SelectColorWnd::sigSetColor,this,&CanvasScene::onSetColor);
}
void CanvasScene::setBrushState(BrushState brush)
{
m_brushState=brush;
}
void CanvasScene::setLineWidth(int nLineWidth)
{
m_nPenWidth=nLineWidth;
}
void CanvasScene::calculateRectAndColor()
{
int nWH=12;
int nColumns=m_image.width()/nWH;
int nRows=m_image.height()/nWH;
RectAndColor rectAndColor;
for (int i=1;i<=nColumns;i++) {
for (int j=1;j<=nRows;j++) {
rectAndColor.color=m_image.pixel(i*nWH-6,j*nWH-6);
rectAndColor.rect.setRect((i-1)*nWH,(j-1)*nWH,nWH,nWH);
rectAndColor.bIsFuzzy=false;
m_vRectAndColor.push_back(rectAndColor);
}
}
}
void CanvasScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
m_vRectAndColor.clear();
emit toolbarTopSignal();
if (mouseEvent->button() != Qt::LeftButton)
return;
m_bIsMousePress=true;
m_prevPoint=mouseEvent->scenePos();
switch (m_brushState) {
case BRUSH_ENUM:
{
m_linePathItem=new QGraphicsPathItem();
m_linePath.clear();
m_linePath.moveTo(m_prevPoint);
break;
}
case RECT_ENUM:
{
m_rectItem= new QGraphicsRectItem();
break;
}
case LINE_ENUM:
{
m_lineItem=new QGraphicsLineItem();
break;
}
case ROUND_ENUM:
m_ellipseItem= new QGraphicsEllipseItem();
break;
case ARROW_ENUM:
m_pathItem= new QGraphicsPathItem();
break;
case TEXT_ENUM:
{
if(m_bIsAddText)
{
m_textItem=new TextItem();
m_textItem->setPos(m_prevPoint);
m_textItem->setDefaultTextColor(m_color);
m_textItem->setFlags(QGraphicsItem::ItemIsMovable|QGraphicsItem::ItemIsFocusable|QGraphicsItem::ItemIsSelectable);
// m_textItem->setFocus();
m_textItem->setTextInteractionFlags(Qt::TextEditable|Qt::TextEditorInteraction);
QFont font;
font.setPixelSize(30);
m_textItem->setFont(font);
m_textItem->setPlainText(" ");
connect(m_textItem, &TextItem::lostFocus,
this, &CanvasScene::editorLostFocus);
connect(m_textItem, &TextItem::selectedChange,
this, &CanvasScene::itemSelected);
addItem(m_textItem);
invalidate();
m_bIsAddText=false;
}
else{
m_bIsAddText=true;
}
break;
}
case MOSAIC_ENUM:
//m_eraser=new Eraser();
QDesktopWidget *desk = QApplication::desktop();
QScreen *screen = QGuiApplication::primaryScreen();
QPixmap pix= screen->grabWindow(desk->winId());
m_image = pix.toImage();
calculateRectAndColor();
break;
}
QGraphicsScene::mousePressEvent(mouseEvent);
}
void CanvasScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
// emit toolbarTopSignal();
if (!m_bIsMousePress)
return;
m_curPoint = mouseEvent->scenePos();
QPen pen;
pen.setColor(m_color);
pen.setWidth(m_nPenWidth);
switch (m_brushState) {
case BRUSH_ENUM:
{
m_linePath.lineTo(m_prevPoint);
// m_lineItem= new QGraphicsLineItem(m_prevPoint.x(),m_prevPoint.y(),
// m_curPoint.x(),m_curPoint.y());
m_linePathItem->setPen(pen);
m_linePathItem->setPath(m_linePath);
this->addItem(m_linePathItem);
m_prevPoint = m_curPoint;
break;
}
case RECT_ENUM:
{
int w=qAbs(m_curPoint.x()-m_prevPoint.x());
int h=qAbs(m_curPoint.y()-m_prevPoint.y());
if( m_curPoint.x()-m_prevPoint.x()<0&&m_curPoint.y()-m_prevPoint.y())
m_rectItem->setRect(m_prevPoint.x()-w,m_prevPoint.y()-h,w,h);
else if(m_curPoint.x()-m_prevPoint.x()<0)
m_rectItem->setRect(m_prevPoint.x()-w,m_prevPoint.y(),w,h);
else if(m_curPoint.y()-m_prevPoint.y()<0)
m_rectItem->setRect(m_prevPoint.x(),m_prevPoint.y()-h,w,h);
else
m_rectItem->setRect(m_prevPoint.x(),m_prevPoint.y(),w,h);
m_rectItem->setPen(pen);
addItem(m_rectItem);
break;
}
case LINE_ENUM:
{
m_lineItem->setLine(m_prevPoint.x(),m_prevPoint.y(),
m_curPoint.x(),m_curPoint.y());
m_lineItem->setPen(pen);
addItem(m_lineItem);
break;
}
case ROUND_ENUM:
{
int w=qAbs(m_curPoint.x()-m_prevPoint.x());
int h=qAbs(m_curPoint.y()-m_prevPoint.y());
if( m_curPoint.x()-m_prevPoint.x()<0&&m_curPoint.y()-m_prevPoint.y())
m_ellipseItem->setRect(m_prevPoint.x()-w,m_prevPoint.y()-h,w,h);
else if(m_curPoint.x()-m_prevPoint.x()<0)
m_ellipseItem->setRect(m_prevPoint.x()-w,m_prevPoint.y(),w,h);
else if(m_curPoint.y()-m_prevPoint.y()<0)
m_ellipseItem->setRect(m_prevPoint.x(),m_prevPoint.y()-h,w,h);
else
m_ellipseItem->setRect(m_prevPoint.x(),m_prevPoint.y(),w,h);
m_ellipseItem->setPen(pen);
addItem(m_ellipseItem);
break;
}
case ARROW_ENUM:
{
int x=m_prevPoint.x();
int y=m_prevPoint.y();
int x1=m_curPoint.x();
int y1=m_curPoint.y();
int x2=x+(x1-x)/4*3;
int y2=y+(y1-y)/4*3;
int x3;
int y3;
if(y1<y)
{
x3=x-x1;
y3=y-y1;
}
else
{
x3=x1-x;
y3=y1-y;
}
double xrad=atan2(y3,x3);
float degrees= qAbs(qRadiansToDegrees(xrad));
if(degrees!=0 && degrees!=180)
{
degrees-=90;
}
QPainterPath path;
QPoint point1={x-5,y2};
QPoint point2={x-12,y2+5};
// QPoint point3={x1,y1};
QPoint point3={x,y1};
QPoint point4={x+12,y2+5};
QPoint point5={x+5,y2};
QPoint point6={x,y};
path.moveTo(m_prevPoint);
path.lineTo(point1);
path.lineTo(point2);
path.lineTo(point3);
path.lineTo(point4);
path.lineTo(point5);
path.lineTo(point6);
// pen.setBrush(QBrush(m_color));
m_pathItem->setBrush(QBrush(m_color));
m_pathItem->setPath(path);
m_pathItem->setPen(pen);
m_pathItem->setRotation(degrees);
qDebug()<<"========="<<degrees<<"=============";
m_pathItem->setTransformOriginPoint(x,y);
addItem(m_pathItem);
break;
}
case TEXT_ENUM:
break;
case MOSAIC_ENUM:
{
QPoint center;
for (int i=0;i<m_vRectAndColor.count();i++) {
if(m_vRectAndColor[i].rect.contains(m_curPoint.x(),m_curPoint.y(),true) && !m_vRectAndColor[i].bIsFuzzy)
{
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
center={m_vRectAndColor[i].rect.x(),m_vRectAndColor[i].rect.y()};
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
break;
}
}
for (int i=0;i<m_vRectAndColor.count();i++) {
//左上
if (m_vRectAndColor[i].rect.x()== center.x()-m_vRectAndColor[i].rect.width() && m_vRectAndColor[i].rect.y()==center.y()-m_vRectAndColor[i].rect.height() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//正上
else if (m_vRectAndColor[i].rect.x()== center.x() && m_vRectAndColor[i].rect.y()==center.y()-m_vRectAndColor[i].rect.height() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//右上
else if (m_vRectAndColor[i].rect.x()== center.x()+m_vRectAndColor[i].rect.width() && m_vRectAndColor[i].rect.y()==center.y()-m_vRectAndColor[i].rect.height() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//左
else if (m_vRectAndColor[i].rect.x()== center.x()-m_vRectAndColor[i].rect.width() && m_vRectAndColor[i].rect.y()==center.y() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//右
else if(m_vRectAndColor[i].rect.x()== center.x()+m_vRectAndColor[i].rect.width() && m_vRectAndColor[i].rect.y()==center.y() && !m_vRectAndColor[i].bIsFuzzy)
{
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//左下
else if (m_vRectAndColor[i].rect.x()== center.x()-m_vRectAndColor[i].rect.width() && m_vRectAndColor[i].rect.y()==center.y() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//正下
else if (m_vRectAndColor[i].rect.x()== center.x() && m_vRectAndColor[i].rect.y()==center.y()+m_vRectAndColor[i].rect.height() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
//右下
else if (m_vRectAndColor[i].rect.x()== center.x()+m_vRectAndColor[i].rect.width() && m_vRectAndColor[i].rect.y()==center.y()+m_vRectAndColor[i].rect.height() && !m_vRectAndColor[i].bIsFuzzy) {
QGraphicsBlurEffect effect;
effect.setBlurRadius(100);
m_vRectAndColor[i].bIsFuzzy=true;
m_rectItem =new QGraphicsRectItem();
m_rectItem->setRect(m_vRectAndColor[i].rect);
m_rectItem->setBrush(m_vRectAndColor[i].color);
pen.setColor(m_vRectAndColor[i].color);
pen.setWidth(1);
m_rectItem->setPen(pen);
m_rectItem->setGraphicsEffect(&effect);
addItem(m_rectItem);
emit addItemSignal(MOSAIC_ENUM,m_rectItem);
}
}
break;
}
}
invalidate();
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
void CanvasScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
m_bIsMousePress=false;
switch (m_brushState) {
case BRUSH_ENUM:
{
emit addItemSignal(BRUSH_ENUM,m_linePathItem);
break;
}
case RECT_ENUM:
{
emit addItemSignal(RECT_ENUM,m_rectItem);
break;
}
case LINE_ENUM:
{
emit addItemSignal(LINE_ENUM,m_lineItem);
break;
}
case ROUND_ENUM:
emit addItemSignal(ROUND_ENUM,m_ellipseItem);
break;
case ARROW_ENUM:
emit addItemSignal(ARROW_ENUM,m_pathItem);
break;
case TEXT_ENUM:
{
if(m_bIsAddText&&m_textItem->toPlainText()!=" ")
emit addItemSignal(TEXT_ENUM,m_textItem);
break;
}
case MOSAIC_ENUM:
// emit addItemSignal(MOSAIC_ENUM,m_rectItem);
break;
}
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
void CanvasScene::onSetColor(QString color)
{
QString str=color.mid(1);
QString str2;
bool ok;
int a=255;
if(str.count()==8)
{
str2=color.mid(1,2);
a=str2.toUInt(&ok,16);
}
m_color=str.toUInt(nullptr,16);
m_color.setAlpha(a);
}
void CanvasScene::editorLostFocus(TextItem *item)
{
QTextCursor cursor = item->textCursor();
cursor.clearSelection();
item->setTextCursor(cursor);
if (item->toPlainText().isEmpty()) {
removeItem(item);
item->deleteLater();
}
}