Qt 简易画板
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt 简易画板相关的知识,希望对你有一定的参考价值。
用Qt框架搭建一个简易画板
需求
- 绘制线、椭圆、矩形框、任意凹/凸多边形、曲线
- 删除最近的图形实例
思路
- 用list保存绘制的图形实例,便于删除
- 对于line、rectangle、ellipse 只要保存初始位置和结束位置
- 对于任意凸/凹多边形可以用一个list保存点集
- 利用Graphics View 管理图形对象
- Graphics View 是M-V框架,model指的是各种图形对象,view指的是视角
- 使用过程是:创建一个scene,创建line和rectangle等图形实例,再使用scene的add函数将line、rectangle实例等添加到scene中,最后通过视口view就可以看到了;同一个model可以从不同的view进行观察
- 创建图形对象继承于父类Shape,绘制完毕后将图形对象存储在List中,点击删除按钮时,从List中出栈一个图形对象,重绘
- 界面样式
- 按钮描述(从左至右)
直线按钮:点击进入绘制直线模式:按下左键设置起始点,拖动鼠标至结束点,释放左键绘制完毕
矩形按钮:点击进入绘制矩形模式:按下左键设置左上角,拖动鼠标至结束点,释放左键绘制完毕
椭圆按钮:点击进入绘制椭圆模式:同矩形按钮
多边形按钮:点击进入绘制多边形模式:单击左键设置起始点,拖动鼠标至下一个转折点,继续单击鼠标添加转折点,直到单击右键结束绘制
曲线按钮:点击进入绘制曲线模式:左键按下并拖动鼠标绘制
删除按钮:点击进入删除模式:逆序删除绘制的图形对象
问题解决Q&A
1.问题: 在Qt中,添加类之后经常出现“无法解析的外部命令的问题”
解决方法:http://blog.csdn.net/yz960611/article/details/50735406
http://blog.csdn.net/zhoxier/article/details/8619688
Tuitor
1.创建主界面
这一步主要是mainWindow.cpp、mainWindow.h、mainWindow.ui三个文件
- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
- 在mainWindow.h中添加头文件
#include<vector>
#include<shape.h>//后面会讲到
- 添加成员变量
```cpp
private:
Shape::drawMode mode;//保存目前的绘图模式,分为七中,在shape.h中定义
Shape *shape;//五种不同的图形对象
bool isDone=false;//是否绘制完毕
QList shapeList;//保存图形对象
QVector polygon_point_array;//保存正在绘制的多边形的点
QVector freehand_point_array;//保存正在绘制的曲线的点
QPoint freePoint;//鼠标当前位置
* 添加成员函数
```cpp
protected:
void paintEvent(QPaintEvent *event);//绘图事件,用update()调用
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
- 编写界面
仿照主界面示意图添加组件,具体使用方法查看Qt Designer,使用设计模式创建界面
(基本步骤:1、创建actionLine;2、编辑图标;3、添加statusTip;4、转到槽函数;)
2、创建各种图形对象的父类——Shape类
(1、右键单击工程;2、添加新文件;2、C++ Class;3、Define Class)
```cpp
//shape.h
ifndef SHAPE_H
define SHAPE_H
include
include
用Qt框架搭建一个简易画板
需求
- 绘制线、椭圆、矩形框、任意凹/凸多边形、曲线
- 删除最近的图形实例
思路
- 用list保存绘制的图形实例,便于删除
- 对于line、rectangle、ellipse 只要保存初始位置和结束位置
- 对于任意凸/凹多边形可以用一个list保存点集
- 利用Graphics View 管理图形对象
- Graphics View 是M-V框架,model指的是各种图形对象,view指的是视角
- 使用过程是:创建一个scene,创建line和rectangle等图形实例,再使用scene的add函数将line、rectangle实例等添加到scene中,最后通过视口view就可以看到了;同一个model可以从不同的view进行观察
- 创建图形对象继承于父类Shape,绘制完毕后将图形对象存储在List中,点击删除按钮时,从List中出栈一个图形对象,重绘
- 界面样式
- 按钮描述(从左至右)
直线按钮:点击进入绘制直线模式:按下左键设置起始点,拖动鼠标至结束点,释放左键绘制完毕
矩形按钮:点击进入绘制矩形模式:按下左键设置左上角,拖动鼠标至结束点,释放左键绘制完毕
椭圆按钮:点击进入绘制椭圆模式:同矩形按钮
多边形按钮:点击进入绘制多边形模式:单击左键设置起始点,拖动鼠标至下一个转折点,继续单击鼠标添加转折点,直到单击右键结束绘制
曲线按钮:点击进入绘制曲线模式:左键按下并拖动鼠标绘制
删除按钮:点击进入删除模式:逆序删除绘制的图形对象
问题解决Q&A
1.问题: 在Qt中,添加类之后经常出现“无法解析的外部命令的问题”
解决方法:http://blog.csdn.net/yz960611/article/details/50735406
http://blog.csdn.net/zhoxier/article/details/8619688
Tuitor
1.创建主界面
这一步主要是mainWindow.cpp、mainWindow.h、mainWindow.ui三个文件
- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
- 在mainWindow.h中添加头文件
#include<vector>
#include<shape.h>//后面会讲到
- 添加成员变量
```cpp
private:
Shape::drawMode mode;//保存目前的绘图模式,分为七中,在shape.h中定义
Shape *shape;//五种不同的图形对象
bool isDone=false;//是否绘制完毕
QList shapeList;//保存图形对象
QVector polygon_point_array;//保存正在绘制的多边形的点
QVector freehand_point_array;//保存正在绘制的曲线的点
QPoint freePoint;//鼠标当前位置
* 添加成员函数
```cpp
protected:
void paintEvent(QPaintEvent *event);//绘图事件,用update()调用
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
- 编写界面
仿照主界面示意图添加组件,具体使用方法查看Qt Designer,使用设计模式创建界面
(基本步骤:1、创建actionLine;2、编辑图标;3、添加statusTip;4、转到槽函数;)
2、创建各种图形对象的父类——Shape类
(1、右键单击工程;2、添加新文件;2、C++ Class;3、Define Class)
```cpp
//shape.h
ifndef SHAPE_H
define SHAPE_H
include
include
用Qt框架搭建一个简易画板
需求
- 绘制线、椭圆、矩形框、任意凹/凸多边形、曲线
- 删除最近的图形实例
思路
- 用list保存绘制的图形实例,便于删除
- 对于line、rectangle、ellipse 只要保存初始位置和结束位置
- 对于任意凸/凹多边形可以用一个list保存点集
- 利用Graphics View 管理图形对象
- Graphics View 是M-V框架,model指的是各种图形对象,view指的是视角
- 使用过程是:创建一个scene,创建line和rectangle等图形实例,再使用scene的add函数将line、rectangle实例等添加到scene中,最后通过视口view就可以看到了;同一个model可以从不同的view进行观察
- 创建图形对象继承于父类Shape,绘制完毕后将图形对象存储在List中,点击删除按钮时,从List中出栈一个图形对象,重绘
- 界面样式
- 按钮描述(从左至右)
直线按钮:点击进入绘制直线模式:按下左键设置起始点,拖动鼠标至结束点,释放左键绘制完毕
矩形按钮:点击进入绘制矩形模式:按下左键设置左上角,拖动鼠标至结束点,释放左键绘制完毕
椭圆按钮:点击进入绘制椭圆模式:同矩形按钮
多边形按钮:点击进入绘制多边形模式:单击左键设置起始点,拖动鼠标至下一个转折点,继续单击鼠标添加转折点,直到单击右键结束绘制
曲线按钮:点击进入绘制曲线模式:左键按下并拖动鼠标绘制
删除按钮:点击进入删除模式:逆序删除绘制的图形对象
问题解决Q&A
1.问题: 在Qt中,添加类之后经常出现“无法解析的外部命令的问题”
解决方法:http://blog.csdn.net/yz960611/article/details/50735406
http://blog.csdn.net/zhoxier/article/details/8619688
Tuitor
1.创建主界面
这一步主要是mainWindow.cpp、mainWindow.h、mainWindow.ui三个文件
- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
- 在mainWindow.h中添加头文件
#include<vector>
#include<shape.h>//后面会讲到
- 添加成员变量
```cpp
private:
Shape::drawMode mode;//保存目前的绘图模式,分为七中,在shape.h中定义
Shape *shape;//五种不同的图形对象
bool isDone=false;//是否绘制完毕
QList shapeList;//保存图形对象
QVector polygon_point_array;//保存正在绘制的多边形的点
QVector freehand_point_array;//保存正在绘制的曲线的点
QPoint freePoint;//鼠标当前位置
* 添加成员函数
```cpp
protected:
void paintEvent(QPaintEvent *event);//绘图事件,用update()调用
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
- 编写界面
仿照主界面示意图添加组件,具体使用方法查看Qt Designer,使用设计模式创建界面
(基本步骤:1、创建actionLine;2、编辑图标;3、添加statusTip;4、转到槽函数;)
2、创建各种图形对象的父类——Shape类
(1、右键单击工程;2、添加新文件;2、C++ Class;3、Define Class)
```cpp
//shape.h
ifndef SHAPE_H
define SHAPE_H
include
include
用Qt框架搭建一个简易画板
需求
- 绘制线、椭圆、矩形框、任意凹/凸多边形、曲线
- 删除最近的图形实例
思路
- 用list保存绘制的图形实例,便于删除
- 对于line、rectangle、ellipse 只要保存初始位置和结束位置
- 对于任意凸/凹多边形可以用一个list保存点集
- 利用Graphics View 管理图形对象
- Graphics View 是M-V框架,model指的是各种图形对象,view指的是视角
- 使用过程是:创建一个scene,创建line和rectangle等图形实例,再使用scene的add函数将line、rectangle实例等添加到scene中,最后通过视口view就可以看到了;同一个model可以从不同的view进行观察
- 创建图形对象继承于父类Shape,绘制完毕后将图形对象存储在List中,点击删除按钮时,从List中出栈一个图形对象,重绘
- 界面样式
- 按钮描述(从左至右)
直线按钮:点击进入绘制直线模式:按下左键设置起始点,拖动鼠标至结束点,释放左键绘制完毕
矩形按钮:点击进入绘制矩形模式:按下左键设置左上角,拖动鼠标至结束点,释放左键绘制完毕
椭圆按钮:点击进入绘制椭圆模式:同矩形按钮
多边形按钮:点击进入绘制多边形模式:单击左键设置起始点,拖动鼠标至下一个转折点,继续单击鼠标添加转折点,直到单击右键结束绘制
曲线按钮:点击进入绘制曲线模式:左键按下并拖动鼠标绘制
删除按钮:点击进入删除模式:逆序删除绘制的图形对象
问题解决Q&A
1.问题: 在Qt中,添加类之后经常出现“无法解析的外部命令的问题”
解决方法:http://blog.csdn.net/yz960611/article/details/50735406
http://blog.csdn.net/zhoxier/article/details/8619688
Tuitor
1.创建主界面
这一步主要是mainWindow.cpp、mainWindow.h、mainWindow.ui三个文件
- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
- 在mainWindow.h中添加头文件
#include<vector>
#include<shape.h>//后面会讲到
- 添加成员变量
```cpp
private:
Shape::drawMode mode;//保存目前的绘图模式,分为七中,在shape.h中定义
Shape *shape;//五种不同的图形对象
bool isDone=false;//是否绘制完毕
QList shapeList;//保存图形对象
QVector polygon_point_array;//保存正在绘制的多边形的点
QVector freehand_point_array;//保存正在绘制的曲线的点
QPoint freePoint;//鼠标当前位置
* 添加成员函数
```cpp
protected:
void paintEvent(QPaintEvent *event);//绘图事件,用update()调用
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
- 编写界面
仿照主界面示意图添加组件,具体使用方法查看Qt Designer,使用设计模式创建界面
(基本步骤:1、创建actionLine;2、编辑图标;3、添加statusTip;4、转到槽函数;)
2、创建各种图形对象的父类——Shape类
(1、右键单击工程;2、添加新文件;2、C++ Class;3、Define Class)
```cpp
//shape.h
ifndef SHAPE_H
define SHAPE_H
include
include
用Qt框架搭建一个简易画板
需求
- 绘制线、椭圆、矩形框、任意凹/凸多边形、曲线
- 删除最近的图形实例
思路
- 用list保存绘制的图形实例,便于删除
- 对于line、rectangle、ellipse 只要保存初始位置和结束位置
- 对于任意凸/凹多边形可以用一个list保存点集
- 利用Graphics View 管理图形对象
- Graphics View 是M-V框架,model指的是各种图形对象,view指的是视角
- 使用过程是:创建一个scene,创建line和rectangle等图形实例,再使用scene的add函数将line、rectangle实例等添加到scene中,最后通过视口view就可以看到了;同一个model可以从不同的view进行观察
- 创建图形对象继承于父类Shape,绘制完毕后将图形对象存储在List中,点击删除按钮时,从List中出栈一个图形对象,重绘
- 界面样式
- 按钮描述(从左至右)
直线按钮:点击进入绘制直线模式:按下左键设置起始点,拖动鼠标至结束点,释放左键绘制完毕
矩形按钮:点击进入绘制矩形模式:按下左键设置左上角,拖动鼠标至结束点,释放左键绘制完毕
椭圆按钮:点击进入绘制椭圆模式:同矩形按钮
多边形按钮:点击进入绘制多边形模式:单击左键设置起始点,拖动鼠标至下一个转折点,继续单击鼠标添加转折点,直到单击右键结束绘制
曲线按钮:点击进入绘制曲线模式:左键按下并拖动鼠标绘制
删除按钮:点击进入删除模式:逆序删除绘制的图形对象
问题解决Q&A
1.问题: 在Qt中,添加类之后经常出现“无法解析的外部命令的问题”
解决方法:http://blog.csdn.net/yz960611/article/details/50735406
http://blog.csdn.net/zhoxier/article/details/8619688
Tuitor
1.创建主界面
这一步主要是mainWindow.cpp、mainWindow.h、mainWindow.ui三个文件
- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
- 在mainWindow.h中添加头文件
#include<vector>
#include<shape.h>//后面会讲到
- 添加成员变量
```cpp
private:
Shape::drawMode mode;//保存目前的绘图模式,分为七中,在shape.h中定义
Shape *shape;//五种不同的图形对象
bool isDone=false;//是否绘制完毕
QList shapeList;//保存图形对象
QVector polygon_point_array;//保存正在绘制的多边形的点
QVector freehand_point_array;//保存正在绘制的曲线的点
QPoint freePoint;//鼠标当前位置
* 添加成员函数
```cpp
protected:
void paintEvent(QPaintEvent *event);//绘图事件,用update()调用
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
- 编写界面
仿照主界面示意图添加组件,具体使用方法查看Qt Designer,使用设计模式创建界面
(基本步骤:1、创建actionLine;2、编辑图标;3、添加statusTip;4、转到槽函数;)
2、创建各种图形对象的父类——Shape类
(1、右键单击工程;2、添加新文件;2、C++ Class;3、Define Class)
```cpp
//shape.h
ifndef SHAPE_H
define SHAPE_H
用Qt框架搭建一个简易画板
需求
- 绘制线、椭圆、矩形框、任意凹/凸多边形、曲线
- 删除最近的图形实例
思路
- 用list保存绘制的图形实例,便于删除
- 对于line、rectangle、ellipse 只要保存初始位置和结束位置
- 对于任意凸/凹多边形可以用一个list保存点集
- 利用Graphics View 管理图形对象
- Graphics View 是M-V框架,model指的是各种图形对象,view指的是视角
- 使用过程是:创建一个scene,创建line和rectangle等图形实例,再使用scene的add函数将line、rectangle实例等添加到scene中,最后通过视口view就可以看到了;同一个model可以从不同的view进行观察
- 创建图形对象继承于父类Shape,绘制完毕后将图形对象存储在List中,点击删除按钮时,从List中出栈一个图形对象,重绘
- 界面样式
- 按钮描述(从左至右)
直线按钮:点击进入绘制直线模式:按下左键设置起始点,拖动鼠标至结束点,释放左键绘制完毕
矩形按钮:点击进入绘制矩形模式:按下左键设置左上角,拖动鼠标至结束点,释放左键绘制完毕
椭圆按钮:点击进入绘制椭圆模式:同矩形按钮
多边形按钮:点击进入绘制多边形模式:单击左键设置起始点,拖动鼠标至下一个转折点,继续单击鼠标添加转折点,直到单击右键结束绘制
曲线按钮:点击进入绘制曲线模式:左键按下并拖动鼠标绘制
删除按钮:点击进入删除模式:逆序删除绘制的图形对象
问题解决Q&A
1.问题: 在Qt中,添加类之后经常出现“无法解析的外部命令的问题”
解决方法:http://blog.csdn.net/yz960611/article/details/50735406
http://blog.csdn.net/zhoxier/article/details/8619688Tuitor
1.创建主界面
这一步主要是mainWindow.cpp、mainWindow.h、mainWindow.ui三个文件- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
- 在mainWindow.h中添加头文件
#include<vector>
#include<shape.h>//后面会讲到
- 添加成员变量
```cpp
private:
Shape::drawMode mode;//保存目前的绘图模式,分为七中,在shape.h中定义
Shape *shape;//五种不同的图形对象
bool isDone=false;//是否绘制完毕
QListshapeList;//保存图形对象
QVectorpolygon_point_array;//保存正在绘制的多边形的点
QVectorfreehand_point_array;//保存正在绘制的曲线的点
QPoint freePoint;//鼠标当前位置
- 新建Qt Widegts Application,项目名是miniDraw,基类是QMainWindow,类名是MainWindow,头文件mainWindow.h,源文件mainWindow.cpp,勾选创建界面。
* 添加成员函数
```cpp
protected:
void paintEvent(QPaintEvent *event);//绘图事件,用update()调用
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void mouseReleaseEvent(QMouseEvent *event);//鼠标释放
- 编写界面
仿照主界面示意图添加组件,具体使用方法查看Qt Designer,使用设计模式创建界面
(基本步骤:1、创建actionLine;2、编辑图标;3、添加statusTip;4、转到槽函数;)
2、创建各种图形对象的父类——Shape类
(1、右键单击工程;2、添加新文件;2、C++ Class;3、Define Class)
```cpp
//shape.h
ifndef SHAPE_H
include
class Shape
{
public:
enum drawMode//绘图模式
{
LINE,
RECT,
ELLIPSE,
POLYGON,
FREEHAND,
DELETE,
DEFAULT
};
Shape();
virtual ~Shape();//虚函数,防止内存泄漏,具体见后面
void setStart(QPoint start)
{
this->start=start;
}
void setEnd(QPoint end)
{
this->end=end;
}
QPoint getStart()
{
return start;
}
QPoint getEnd()
{
return end;
}
void virtual paint(QPainter &painter)=0;//需要在子类中重写的函数设置为虚函数
protected:
QPoint start,end;
};
endif // SHAPE_H
```cpp
//shape.cpp
#include "shape.h"
Shape::Shape()
{
}
```cpp
//shape.cpp
#include "shape.h"
Shape::Shape()
{
}
2.1创建子类line、Rectangle、Ellipse、Polygon、FreeHand——主要是重写paint函数
- line
```cpp
void line::paint(QPainter &painter)
{
painter.drawLine(start,end);
}
* **rectangle**
```cpp
void Rectangle::paint(QPainter &painter)
{
painter.drawRect(start.x(),start.y(),end.x()-start.x(),end.y()-start.y());
}
- ellipse
void Ellipse::paint(QPainter &painter)
{
painter.drawEllipse(start.x(),start.y(),end.x()-start.x(),end.y()-start.y());
}
以上这些都很简单
- freehand
```cpp
//freehand.h
ifndef FREEHAND_H
define FREEHAND_H
include"shape.h"
include
include"shape.h"
include
class FreeHand:public Shape
{
public:
FreeHand();
FreeHand(const QVector
void paint(QPainter &painter);
protected:
QVector
};
endif // FREEHAND_H
```cpp
//构造函数和绘制函数的实现
FreeHand::FreeHand(const QVector<QPoint> &point_array)
{
for(size_t i=0;i<point_array.size();i++)
{
//free_point_array[i]=point_array[i];
free_point_array.push_back(point_array[i]);
}
}
void FreeHand::paint(QPainter &painter)
{
for(size_t i=0;i<free_point_array.size()-1;i++)
{
painter.drawLine(free_point_array[i],free_point_array[i+1]);
}
}
- polygon
```cpp
//构造函数和绘图函数的实现
Polygon::Polygon(const QVector &points)
{
for(size_t i=0;i<points.size();i++)
{
pointList.push_back(points[i]);
}
}
void Polygon::paint(QPainter &painter)
{
for(size_t i=0;i<pointList.size()-1;i++)
{
painter.drawLine(pointList[i],pointList[i+1]);
}
painter.drawLine(pointList.back(),pointList.front());
}
**以上两个是比较难的,需要考虑一下**
**3整体逻辑——对成员函数的实现**
**3.1给按钮添加槽函数**
(这里我是采用Qt Creator 添加的,这不是我们讲的重点)
```cpp
void MainWindow::on_actionLine_triggered()
{
mode=Shape::drawMode::LINE;
}
void MainWindow::on_actionRectangle_triggered()
{
mode=Shape::drawMode::RECT;
}
void MainWindow::on_actionEllipse_triggered()
{
mode=Shape::drawMode::ELLIPSE;
}
void MainWindow::on_actionPolygon_triggered()
{
mode=Shape::drawMode::POLYGON;
}
void MainWindow::on_actionFreehand_triggered()
{
mode=Shape::drawMode::FREEHAND;
}
void MainWindow::on_actionDelete_triggered()
{
mode=Shape::drawMode::DELETE;
if(!shapeList.isEmpty())
{
shapeList.pop_back();//最后一个图形对象出栈
mode=Shape::DEFAULT;//设置模式为默认模式
update();
}
}
逻辑就是点击不同的按钮进入不同的绘制模式
3.2给鼠标按键添加监听
- 绘制直线:按下鼠标左键拖动鼠标,直到目的位置释放鼠标;
- 绘制矩形:同绘制直线;
- 绘制椭圆:同绘制矩形
- 绘制多边形:点击鼠标左键设置第一个锚点,再次单击设置第二个锚点,以此类推,设置完最后一个锚点后点击鼠标右键结束绘制;
- 绘制曲线:按住左键不放绘制曲线,释放左键结束绘制
- 从功能需求我们可以看出,绘制直线、矩形、椭圆实际上只需要两个点就可以确定,那么就可以按按下鼠标的位置作为起始位置,释放鼠标的位置作为结束位置
- 绘制多边形和绘制曲线很相似,就是往vector里面添加一系列点
- 因此,在绘制直线、椭圆、矩形的时候,可以在按下左键的时候就将图形对象保存进shapeList
- 在绘制曲线、多边形时可以在主函数里面暂存这一系列点,等绘制完毕再把图形对象保存进shapeList,这样可以提高绘制的效率
```cpp
//鼠标按下
void MainWindow::mousePressEvent(QMouseEvent *event)
{
switch (event->button()) {
case Qt::LeftButton ://在绘制直线、矩形、多边形、椭圆、曲线时有效,开始绘制
switch (mode) {
case Shape::DEFAULT:
break;
case Shape::DELETE:
//do nothing
break;
case Shape::LINE:
shape=new line;
break;
case Shape::RECT:
shape=new Rectangle;
break;
case Shape::ELLIPSE:
shape=new Ellipse;
break;
case Shape::FREEHAND:
shape=new FreeHand;
break;
case Shape::POLYGON:
shape=new Polygon;
break;
default:
break;
}
break;
case Qt::RightButton: //仅在绘制多边形时有效,结束绘制
if(mode==Shape::POLYGON)
{
isDone=true;
if(polygon_point_array.size()>0)
{
shape=new Polygon(polygon_point_array);
shapeList.push_back(shape);
polygon_point_array.clear();
update();
shape=NULL;
}
}
break;
default:
break;
}
if(shape!=NULL){//刚开始绘制
if(mode==Shape::POLYGON)//设置转折点
{
isDone=false;
polygon_point_array.push_back(event->pos());//添加进锚点
freePoint=event->pos();
update();
}else if(mode==Shape::FREEHAND)
{
isDone=false;
freehand_point_array.push_back(event->pos());//添加进锚点
}
else {
isDone=false;
shape->setStart(event->pos());
shape->setEnd(event->pos());
shapeList.push_back(shape);//将图形对象入栈
}
}
}
```cpp
//鼠标移动
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if(shape&&!isDone)
{
if(mode==Shape::FREEHAND)
{
freehand_point_array.push_back(event->pos());//添加曲线点序列
update();
}else
{
shape->setEnd(event->pos());
freePoint=event->pos();
update();
}
}
}
//鼠标释放
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)//仅在左键释放时有效,结束绘制直线、矩形、椭圆、曲线
{
switch (mode) {
case Shape::POLYGON:
break;
case Shape::FREEHAND:
isDone=true;
shape=new FreeHand(freehand_point_array);
freehand_point_array.clear();
shapeList.push_back(shape);
update();
shape=NULL;
break;
default:
isDone=true;
update();
shape=NULL;
break;
}
}
}
```cpp
//构造函数和绘制函数的实现
FreeHand::FreeHand(const QVector<QPoint> &point_array)
{
for(size_t i=0;i<point_array.size();i++)
{
//free_point_array[i]=point_array[i];
free_point_array.push_back(point_array[i]);
}
}
void FreeHand::paint(QPainter &painter)
{
for(size_t i=0;i<free_point_array.size()-1;i++)
{
painter.drawLine(free_point_array[i],free_point_array[i+1]);
}
}
```cpp
//构造函数和绘图函数的实现
Polygon::Polygon(const QVector
{
for(size_t i=0;i<points.size();i++)
{
pointList.push_back(points[i]);
}
}
void Polygon::paint(QPainter &painter)
{
for(size_t i=0;i<pointList.size()-1;i++)
{
painter.drawLine(pointList[i],pointList[i+1]);
}
painter.drawLine(pointList.back(),pointList.front());
}
**以上两个是比较难的,需要考虑一下**
**3整体逻辑——对成员函数的实现**
**3.1给按钮添加槽函数**
(这里我是采用Qt Creator 添加的,这不是我们讲的重点)
```cpp
void MainWindow::on_actionLine_triggered()
{
mode=Shape::drawMode::LINE;
}
void MainWindow::on_actionRectangle_triggered()
{
mode=Shape::drawMode::RECT;
}
void MainWindow::on_actionEllipse_triggered()
{
mode=Shape::drawMode::ELLIPSE;
}
void MainWindow::on_actionPolygon_triggered()
{
mode=Shape::drawMode::POLYGON;
}
void MainWindow::on_actionFreehand_triggered()
{
mode=Shape::drawMode::FREEHAND;
}
void MainWindow::on_actionDelete_triggered()
{
mode=Shape::drawMode::DELETE;
if(!shapeList.isEmpty())
{
shapeList.pop_back();//最后一个图形对象出栈
mode=Shape::DEFAULT;//设置模式为默认模式
update();
}
}
逻辑就是点击不同的按钮进入不同的绘制模式
3.2给鼠标按键添加监听
- 绘制直线:按下鼠标左键拖动鼠标,直到目的位置释放鼠标;
- 绘制矩形:同绘制直线;
- 绘制椭圆:同绘制矩形
- 绘制多边形:点击鼠标左键设置第一个锚点,再次单击设置第二个锚点,以此类推,设置完最后一个锚点后点击鼠标右键结束绘制;
- 绘制曲线:按住左键不放绘制曲线,释放左键结束绘制
- 从功能需求我们可以看出,绘制直线、矩形、椭圆实际上只需要两个点就可以确定,那么就可以按按下鼠标的位置作为起始位置,释放鼠标的位置作为结束位置
- 绘制多边形和绘制曲线很相似,就是往vector里面添加一系列点
- 因此,在绘制直线、椭圆、矩形的时候,可以在按下左键的时候就将图形对象保存进shapeList
- 在绘制曲线、多边形时可以在主函数里面暂存这一系列点,等绘制完毕再把图形对象保存进shapeList,这样可以提高绘制的效率
```cpp
//鼠标按下
void MainWindow::mousePressEvent(QMouseEvent *event)
{
switch (event->button()) {
case Qt::LeftButton ://在绘制直线、矩形、多边形、椭圆、曲线时有效,开始绘制
switch (mode) {
case Shape::DEFAULT:
break;
case Shape::DELETE:
//do nothing
break;
case Shape::LINE:
shape=new line;
break;
case Shape::RECT:
shape=new Rectangle;
break;
case Shape::ELLIPSE:
shape=new Ellipse;
break;
case Shape::FREEHAND:
shape=new FreeHand;
break;
case Shape::POLYGON:
shape=new Polygon;
break;
default:
break;
}
break;
case Qt::RightButton: //仅在绘制多边形时有效,结束绘制
if(mode==Shape::POLYGON)
{
isDone=true;
if(polygon_point_array.size()>0)
{
shape=new Polygon(polygon_point_array);
shapeList.push_back(shape);
polygon_point_array.clear();
update();
shape=NULL;
}
}
break;
default:
break;
}
if(shape!=NULL){//刚开始绘制
if(mode==Shape::POLYGON)//设置转折点
{
isDone=false;
polygon_point_array.push_back(event->pos());//添加进锚点
freePoint=event->pos();
update();
}else if(mode==Shape::FREEHAND)
{
isDone=false;
freehand_point_array.push_back(event->pos());//添加进锚点
}
else {
isDone=false;
shape->setStart(event->pos());
shape->setEnd(event->pos());
shapeList.push_back(shape);//将图形对象入栈
}
}
}
```cpp
//鼠标移动
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if(shape&&!isDone)
{
if(mode==Shape::FREEHAND)
{
freehand_point_array.push_back(event->pos());//添加曲线点序列
update();
}else
{
shape->setEnd(event->pos());
freePoint=event->pos();
update();
}
}
}
//鼠标释放
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)//仅在左键释放时有效,结束绘制直线、矩形、椭圆、曲线
{
switch (mode) {
case Shape::POLYGON:
break;
case Shape::FREEHAND:
isDone=true;
shape=new FreeHand(freehand_point_array);
freehand_point_array.clear();
shapeList.push_back(shape);
update();
shape=NULL;
break;
default:
isDone=true;
update();
shape=NULL;
break;
}
}
}
以上
!--more-->
以上是关于Qt 简易画板的主要内容,如果未能解决你的问题,请参考以下文章