#ifndef MINIWINDOW_H
#define MINIWINDOW_H
#include <QtWidgets/QMainWindow>
#include "ui_miniwindow.h"
#include <QtGui>
#include "shape.h"
#include "paintwidget.h"
#include <QWidget>
#include <QMessageBox>
///
//该类继承了QMainWindow类,使用了Shape类和paintWidget类。
//主要功能:给主窗口布局,添加工具栏(Qmenu),菜单栏(QToolBar),状态栏(QStatus)。
//初始化主窗口的中心部件(central Widget)
//为画板功能提供接口。
//一个信号(signals):changeCurrentShape
//两个槽(slots):drawLineActionTriggered();drawRectActionTriggered();
///
class Miniwindow : public QMainWindow
{
Q_OBJECT
public:
Miniwindow(QWidget *parent = 0);
~Miniwindow();
void About()
{
QMessageBox::information(NULL,"hello","Hello, 994", QMessageBox::Yes);
};
private:
private slots:
//响应动作,然后添加对应参数作为信号实参。再发送
void drawLineActionTriggered();
void drawRectActionTriggered();
signals:
//
//该信号的发射主要用于激活PaintWidget中的形状选择的槽
//void paintwidget::setCurrentshape(Shape::Code s)
/
void changeCurrentShape(Shape::Code newShape);
};
#endif // MINIWINDOW_H
<pre name="code" class="cpp">
<pre name="code" class="cpp">paintwidget.h
#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H
#include <QWidget>
#include "ui_paintwidget.h"
#include <QtGui>
#include <QDebug>
#include "shape.h"
#include "line.h"
#include "rect.h"
#include <QWidget>
/
//该类继承了QWidget类,使用了Shape,Line,Rect类。
//类功能:响应判断中心部件的鼠标动作,并作出相应的回应。
/
class paintwidget : public QWidget
{
Q_OBJECT
public:
paintwidget(QWidget *parent = 0);
~paintwidget();
public slots:
//
//该公用槽的作用就是设定形状,让中心部件知道这时的鼠标
//动作时针对哪些形状活动的,这里使用了一个私有成员,currShapeCode
//Shape::Code,这里的设定主要对下面的函数mousePressEvent有用
//借助这个类型,可以知道在“点击鼠标”的这一动作时使用的是哪种的类型
//从而往内存堆中新建哪种类型的对象
///
void setCurrentShape(Shape::Code s)
{
if (s != currShapeCode)
{
currShapeCode = s;
}
}
protected:
//设置画笔。遍历数据成员链表。通过链表的每个记录,画出全部画出过的图像
void paintEvent(QPaintEvent *event);
void mousePressEvent(QMouseEvent *event); //鼠标点击操作。
void mouseMoveEvent(QMouseEvent *event); //鼠标移动
void mouseReleseEvent(QMouseEvent *event);//鼠标释放。
private:
Shape::Code currShapeCode;
Shape *shape;
bool perm;
QList<Shape*> shapeList;
};
#endif // PAINTWIDGET_H
shape.h
#ifndef SHAPE_H
#define SHAPE_H
#include <QWidget>
#include <QtGui>
#include "ui_shape.h"
//此类用到了QPoint类
class Shape : public QWidget
{
Q_OBJECT
public:
Shape(QWidget *parent = 0);
~Shape();
//区分形状类型
enum Code //枚举
{
Line,
Rect
};
//设置形状开始点的标志位
void setStart(QPoint s)
{
start = s;
}
//设置形状结束点的标准位
void setEnd(QPoint e)
{
end = e;
}
QPoint startPoint()
{
return start;
}
QPoint endPoint()
{
return end;
}
//纯虚函数用于绘图
void virtual paint(QPainter & painter) = 0;
protected:
//设置形状开始点与结束点的标志位
QPoint start;
QPoint end;
};
#endif // SHAPE_H
rect.h
#ifndef RECT_H
#define RECT_H
#include "shape.h"
#include "ui_rect.h"
///
//继承了Shape类。
//功能:实现矩形的绘制功能。
///
class Rect : public Shape
{
Q_OBJECT
public:
Rect(QWidget *parent = 0);
~Rect();
void paint(QPainter & painter);
};
#endif // RECT_H
line.h
#ifndef LINE_H
#define LINE_H
#include "shape.h"
#include "ui_line.h"
///
//继承了Shape类。
//功能:实现直线的绘制功能。
///
class Line : public Shape
{
Q_OBJECT
public:
Line(QWidget *parent = 0);
~Line();
void paint(QPainter & painter);
};
#endif // LINE_H
miniwindow.cpp
#include "miniwindow.h"
#include<QLabel>
#include <QMenu>
//构造函数功能及实现
//1、构造基本部件,工具栏,菜单栏,状态栏动作的初始化。
//2、设定中心部件,使用下面函数将paintwidget与本类相连。
// void QMainWindow::setCentralWidget(QWidget *widget)
//3、连接信号和槽,将动作与本类中的槽slots相连。
// 本次连接的主要目的是将动作与画板功能的实现联系上。
//
Miniwindow::Miniwindow(QWidget *parent)
: QMainWindow(parent)
{
//初始化工具栏
QToolBar *bar = this->addToolBar("Tools");
//QActionGroup的作用就是将多个相似的动作组合在一起。
//作用是bar上面的两个动作Line和Rect同时只能选一个。
QActionGroup *group = new QActionGroup(bar);
//设置Line动作
QAction *drawLineAction = new QAction("Line",bar); //初始化动作drawLineAction
drawLineAction->setToolTip(tr("Draw a line.")); //设置工具栏按钮上的小标签
drawLineAction->setStatusTip(tr("Draw a line")); //设置下面状态栏的标签
drawLineAction->setCheckable(true); //这句和下面一句作用是将按钮设置成可停驻
drawLineAction->setChecked(true); //这句作用是程序开始的时候就停驻。如果在Rect动作中也加入这句,则打开程序两个按钮均是按下状态。
group->addAction(drawLineAction);
bar->addAction(drawLineAction);
//设置Rect动作
QAction *drawRectAction = new QAction("Rectangle",bar);
drawRectAction->setToolTip(tr("Draw a rectangle."));
drawRectAction->setStatusTip(("Draw a rectangle")); //状态栏标题
drawRectAction->setCheckable(true);
group->addAction(drawRectAction);
bar->addAction(drawRectAction);
//设置消息框
QAction *About = new QAction("About",bar);
bar->addAction(About);
connect(About,&QAction::triggered,this,&Miniwindow::About);
//设置下面状态栏
QLabel *statusMsg = new QLabel; //初始化
statusBar()->addWidget(statusMsg); //添加状态栏
//设置菜单栏
QMenu *menu;
menu = menuBar()->addMenu(tr("&Menu"));
//设置中心部件,这里是画板。
//将paintwidget类与本类连接。
paintwidget *paintWidget = new paintwidget(this);
setCentralWidget(paintWidget);
//连接信号
connect(drawLineAction, SIGNAL(triggered()), this, SLOT(drawLineActionTriggered()));
connect(drawRectAction, SIGNAL(triggered()), this, SLOT(drawRectActionTriggered()));
//下面这句话不理解,求解释。为什么发出信号的是this,指什么?
connect(this, SIGNAL(changeCurrentShape(Shape::Code)), paintWidget, SLOT(setCurrentShape(Shape::Code)));
}
Miniwindow::~Miniwindow()
{
}
//emit 发射信号函数
void Miniwindow::drawLineActionTriggered()
{
emit changeCurrentShape(Shape::Line); //设定形状为线形,发射信号。
}
void Miniwindow::drawRectActionTriggered()
{
emit changeCurrentShape(Shape::Rect); //设定形状为矩形,发射信号。
}
paintwidget.cpp
#include "paintwidget.h"
//构造函数
paintwidget::paintwidget(QWidget *parent)
: QWidget(parent), currShapeCode(Shape::Line), shape(NULL), perm(false)
{
//是设置控件在布局里面的大小变化的属性。
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
paintwidget::~paintwidget()
{
}
//设置画笔
void paintwidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this); //初始化画板
painter.setBrush(Qt::white); //填充所限定的矩形区域
//设置左上角顶点是(0,0),宽和长与窗口大小一致。
painter.drawRect(0, 0, size().width(), size().height());
//这里遍历容器可以保留历史痕迹
foreach(Shape *shape, shapeList)
{
shape->paint(painter);
}
if (shape)
{
shape->paint(painter);
}
}
//鼠标点击操作函数
//过程:先判断是哪个图形,新建图形对象,然后新建链表中的类型
// 的单个对象放入链表,并设定该对象的鼠标点击位置作为起点位置。
/
void paintwidget::mousePressEvent(QMouseEvent *event)
{
switch (currShapeCode) //判断是哪种图形
{
case Shape::Line:
{
shape = new Line; //新建线形对象
break;
}
case Shape::Rect:
{
shape = new Rect;
break;
}
}
if (shape != NULL)
{
perm = false;
shapeList << shape; //存入链表
//设定鼠标点击位置为起点。
shape->setStart(event->pos());
shape->setEnd(event->pos());
}
}
//鼠标移动函数
//过程:设定终点,直到它发生鼠标释放事件时才停止
//而判断停止方法可以通过数据成员bool perm,
///
void paintwidget::mouseMoveEvent(QMouseEvent *event)
{
if (shape && !perm) //shape有值,perm为false
{
shape->setEnd(event->pos()); //设定终点。
update(); //更新显示。
}
}
//鼠标释放函数
//将bool perm 设定为真,使其成为显示的判断条件
//成为放入链表的条件
/
void paintwidget::mouseReleseEvent(QMouseEvent *event)
{
perm = true;
}
shape.cpp
#include "shape.h"
Shape::Shape(QWidget *parent)
: QWidget(parent)
{
}
Shape::~Shape()
{
}
line.cpp
#include "line.h"
Line::Line(QWidget *parent)
: Shape(parent)
{
}
Line::~Line()
{
}
void Line::paint(QPainter & painter)
{
painter.drawLine(start, end); //画线函数
}
rect.cpp
#include "rect.h"
Rect::Rect(QWidget *parent)
: Shape(parent)
{
}
Rect::~Rect()
{
}
void Rect::paint(QPainter & painter)
{
painter.drawRect(start.x(), start.y(),end.x() - start.x(), end.y() - start.y()); //画矩形函数
}