1、绘制原理
建立一个Qt Widgets Application 工程
main.cpp 不需添加内容
在mainwindow.h文件添加 void paintEvent(QPaintEvent *event)
在mainwindow.cpp文件重写 void paintEvent(QPaintEvent *event)
重新paintEvent(QPaintEvent *event)时,
会实例化一个Qpainter,每个图形的类内Draw()都会调用Qpainter的对应的画图函数,如drawLine(),drawRect().
重写 void paintEvent(QPaintEvent *event) 如下:
void MainWindow::paintEvent(QPaintEvent *event){
QPainter painter(this);
QPen pen;
pen.setColor(Qt::black); // 设置画笔为黑色
pen.setWidth(3); //设置画笔粗细,太细了,再加上坐标取得太小,绘制出来了,但是看不到,让我崩溃半天
painter.setPen(pen); // 设置画笔
CPoint point1(200,0);
CPoint point2(100,100);
CPoint point3(300,100);
//绘制一个三角形
CTriangle ctri(point1,point2,point3);
// ctri.Draw(painter);
//绘制一个圆1
CCircle cir(point2,50);
//cir.Draw(painter);
//绘制一个圆2
CPoint point4(250,100);
CCircle cir1(point4,50);
//cir1.Draw(painter);
//绘制一个矩形
CPoint point5(300,200);
CRect crect (point2,point5);
//crect.Draw(painter);
//绘制一个在矩形内有圆的组合图形
CPoint point6(175,150);
CircleInRect cirrect(point6,50);
//cirrect.Draw(painter);
//实例化一个管理图形的对象,将所有图形加入管理,统一绘制,依靠多态来实现
ShapeManager shapema;
shapema.Add(&ctri);
shapema.Add(&cir);
shapema.Add(&cir1);
shapema.Add(&crect);
shapema.Add(&cirrect);
shapema.Draw(painter);
//shma.Add(&cir2);
//shma.Draw(painter);
}
1:三角形, 2、3:圆形,4:矩形,5:复合图形
理解Add和Draw的实现原理,代码如下:
void ShapeManager::Add(CShape *pShape){
m_pShape.push_back(pShape);
}
void ShapeManager::Draw(QPainter &painter){
for(vector<CShape*>::iterator it = m_pShape.begin();it!=m_pShape.end();it++)
{
(*it)->Draw(painter);
}
}
Add(CShape pShape)的形参为CSshape类型,根据类型兼容规则,基类的指针可用子类的指针赋值,同时避免不能访问到子类的成员,CShape的函数定义为虚函数式,那么在Draw(QPainter &painter)函数中,(*it)->Draw(painter);访问的Draw就是各子类中的重写的draw()。
2、图形类
1、关系图
2、CShape
class CShape
{
public:
CShape();
CShape(const CShape& shape);
virtual ~CShape();
// virtual double GetArea() const;
// virtual bool ptIn(const CPoint& pt) const;
// virtual bool InRect(const CRect& rc) const;
virtual void Draw(QPainter &painter) const;
// virtual void DrawColor();
// virtual CShape* Clone() const;
// virtual CShape& Move(int nOffsetX, int nOffsetY);
protected:
string m_sName;
};
3、CPoint
class CPoint :virtual public CShape {
public:
int m_nPosX;
int m_nPosY;
CPoint() {
m_nPosX = 0;
m_nPosY = 0;
}
CPoint(int nPosX, int nPosY);
CPoint(const CPoint& pt);
virtual ~CPoint();
// double GetArea() const;
// bool ptIn(const CPoint& pt) const;
// bool InRect(const CRect& rc) const;
void Draw(QPainter &painter) const;
// void DrawColor();
// CPoint* Clone() const;
// CPoint& Move(int nOffsetX, int nOffsetY);
};
4、CTriangle
class CTriangle :virtual public CShape {
public:
CTriangle() {}
CTriangle(const CPoint& pt1, const CPoint& pt2, const CPoint& pt3);
CTriangle(const CTriangle& tri);
//CTriangle(const CPoint& pt);
virtual ~CTriangle();
// double GetArea() const;
// bool ptIn(const CPoint& pt) const;
// bool InRect(const CRect& rc) const;
void Draw(QPainter &painter) const;
// void DrawColor();
// CTriangle* Clone() const;
// CTriangle& Move(int nOffsetX, int nOffsetY);
CPoint m_pts[3];
};
5、CRect
class CRect :virtual public CShape {
public:
CRect() {}
CRect(CPoint pt1, CPoint pt2);
CRect(const CRect& rc);
CRect(CPoint pt1);
virtual ~CRect();
// double GetArea() const;
// bool ptIn(const CPoint& pt) const;
// bool InRect(const CRect& rc) const;
void Draw(QPainter &painter) const;
// void DrawColor();
// CRect* Clone() const;
// CRect& Move(int nOffsetX, int nOffsetY);
CPoint m_ptLT;
CPoint m_ptBR;
};
6、CCircle
class CCircle:virtual public CShape {
public:
CCircle() {}
CCircle(CPoint ptCenter,double dR);
CCircle(const CCircle& rc);
CCircle(CPoint pt1);
virtual ~CCircle();
// double GetArea() const;
// bool ptIn(const CPoint& pt) const;
// bool InRect(const CRect& rc) const;
void Draw(QPainter &painter) const;
// void DrawColor();
// CCircle* Clone() const;
// CCircle& Move(int nOffsetX, int nOffsetY);
CPoint m_ptCenter;
double m_dR;
};
6、CircleInRect
class CircleInRect:public CCircle, public CRect {
public:
CircleInRect() {}
CircleInRect(CPoint ptCenter,double dR);
CircleInRect(const CircleInRect& rc);
CircleInRect(CPoint pt1);
virtual ~CircleInRect();
// double GetArea() const;
// bool ptIn(const CPoint& pt) const;
// bool InRect(const CRect& rc) const;
void Draw(QPainter &painter) const;
// void DrawColor();
// CircleInRect* Clone() const;
// CircleInRect& Move(int nOffsetX, int nOffsetY);
};
正在解决 在mainwindow添加一个shapemanager 来管理界面中的所有图形,shapemanager有vector<shape*>,然后将图形添加到shapemanager统一管理绘制,出现异常终止的问题。
原因:在paintEvent这个函数中,定义图形对象,将他们指针添加到shapemanager的vector中,相当于备份,那么paintEvent函数结束,其中定义的图形对象,生命周期也结束,但是这个vcetor中的指针备份未清除,而界面一直在刷新,paintEvent函数一直在重复执行,那么下次shma.Draw遍历访问的vcetor中的指针时,有无指向的指针,就会程序崩溃。
解决:
方法1、使用new的方法创建图形,同时记的removeall(),
方法2、图形对象不要定义在paintEvent中,