Part 05 简易画板的实现(Qt)[2012.02.13]

来源:互联网 发布:网络图书馆图片素材 编辑:程序博客网 时间:2024/06/13 16:45

 Part 05 简易画板的实现(Qt)

——2012.02.13


0. 本次学习Qt时主要方法:分析代码,理清实现画板功能的思路,弄清各类间的关系。
1. 编写学习笔记主要形式:展示程序功能,展示程序类的功能关系分析图,展示(经修改的)程序代码。
2. 主要参考学习资料: Qt Assistant与Qt学习之路(31)(豆子空间)。
3. 本Part内容:了解QPainter,QPointer,QEvent类的使用,认识Center Widget中功能的实现方法。

 


011 Program –paintApp(Widget)

 

01. 展示程序功能
   
程序有一工具栏,有一画板,刚开始时,画板为空,鼠标指向工具栏第二个选项,在状态栏中有“Draw a rectangle”的提示字样。
  
按下鼠标,拖动,释放,可以得出一个矩形于画板中显示,当多次画时,历史痕迹不会消去。
  
现在开始选中工具栏的第一项,Draw a Line.
  
与上次操作一样,按下鼠标,拖动,释放,可以得出一个直线于画板中显示,当然,每次所画图形如果发生重叠,新画的图形会将旧的图形覆盖。

 


02. 展示程序类的功能关系分析图
 


03. 程序代码

# MyApp.proTARGET = MyAppTEMPLATE = appSOURCES += \    main.cpp \    mainwindow.cpp \    paintwidget.cpp \    line.cpp \    shape.cpp \    rect.cppHEADERS += \    mainwindow.h \    paintwidget.h \    line.h \    shape.h \    rect.hRESOURCES += res.qrc


// main.cpp#include <QtGui/QApplication>#include "mainwindow.h"int main(int argc, char *argv[]){    QApplication app(argc, argv);    MainWindow w;    w.setWindowTitle(QObject::tr("Paint Application"));    w.setWindowIcon(QIcon(":/main.png"));    w.resize(800, 600);    w.show();    return app.exec();}


// mainwindow.h#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QtGui>#include "shape.h"#include "paintwidget.h"class MainWindow : public QMainWindow{    Q_OBJECTpublic:    MainWindow(QWidget *parent = 0);signals:    void changeCurrentShape(Shape::Code newShape);private slots:    void drawLineActionTriggered();    void drawRectActionTriggered();};#endif // MAINWINDOW_H


// PaintWidget.h#ifndef PAINTWIDGET_H#define PAINTWIDGET_H#include <QtGui>#include <QDebug>#include "shape.h"#include "line.h"#include "rect.h"class PaintWidget : public QWidget{    Q_OBJECTpublic:    PaintWidget(QWidget *parent = 0);public slots:    void setCurrentShape(Shape::Code s)    {        if(s != currShapeCode)        {            currShapeCode = s;  // 设定形状        }    }protected:    void paintEvent(QPaintEvent *event);    void mousePressEvent(QMouseEvent *event);    void mouseMoveEvent(QMouseEvent *event);    void mouseReleaseEvent(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 <QtGui>class Shape{public:    enum Code    {        Line,        Rect    };    Shape();    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


// Line.h#ifndef LINE_H#define LINE_H#include "shape.h"class Line : public Shape{public:    Line();    void paint(QPainter &painter);};#endif // LINE_H


// rect.h#ifndef RECT_H#define RECT_H#include "shape.h"class Rect : public Shape{public:    Rect();    void paint(QPainter &painter);};#endif // RECT_H


// mainwindow.cpp#include "mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){// 设置工具栏    QToolBar *bar = this->addToolBar("Tools");    QActionGroup *group = new QActionGroup(bar);// 设置Line动作    QAction *drawLineAction = new QAction("Line", bar);    drawLineAction->setIcon(QIcon(":/line.png"));    drawLineAction->setToolTip(tr("Draw a line."));    drawLineAction->setStatusTip(tr("Draw a line."));    drawLineAction->setCheckable(true);    drawLineAction->setChecked(true);    group->addAction(drawLineAction);    bar->addAction(drawLineAction);// 设置Rect动作    QAction *drawRectAction = new QAction("Rectangle", bar);    drawRectAction->setIcon(QIcon(":/rect.png"));    drawRectAction->setToolTip(tr("Draw a rectangle."));    drawRectAction->setStatusTip(tr("Draw a rectangle."));    drawRectAction->setCheckable(true);    group->addAction(drawRectAction);    bar->addAction(drawRectAction);// 设置状态栏    QLabel *statusMsg = new QLabel;    statusBar()->addWidget(statusMsg);// 设置中心部件    PaintWidget *paintWidget = new PaintWidget(this);    setCentralWidget(paintWidget);// 信号连接    connect(drawLineAction, SIGNAL(triggered()), this, SLOT(drawLineActionTriggered()));    connect(drawRectAction, SIGNAL(triggered()), this, SLOT(drawRectActionTriggered()));    connect(this, SIGNAL(changeCurrentShape(Shape::Code)), paintWidget, SLOT(setCurrentShape(Shape::Code)));}void MainWindow::drawLineActionTriggered(){    emit changeCurrentShape(Shape::Line);   // 设定形状为线形,发射信号}void MainWindow::drawRectActionTriggered(){    emit changeCurrentShape(Shape::Rect);   // 设定形状为Rectangle矩形,发射信号}


// paintwidget.cpp#include "paintwidget.h"PaintWidget::PaintWidget(QWidget *parent)    : QWidget(parent), currShapeCode(Shape::Line), shape(NULL), perm(false){    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);}void PaintWidget::paintEvent(QPaintEvent *event){    QPainter painter(this);    painter.setBrush(Qt::white);    painter.drawRect(0, 0, size().width(), size().height());    foreach(Shape * shape, shapeList)   // 这里遍历容器可以保留历史痕迹    {        shape -> paint(painter);    }    return;}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());    }}void PaintWidget::mouseMoveEvent(QMouseEvent *event){    if(shape && !perm)    {        shape->setEnd(event->pos());        update(); // void QWidget::update() [slot]        // Updates the widget unless updates are disabled or the widget is hidden.        // This function does not cause an immediate repaint;        // instead it schedules a paint event for processing when Qt returns to the main event loop.        // This permits Qt to optimize for more speed and less flicker than a call to repaint() does.        // Calling update() several times normally results in just one QWidget:paintEvent() call.    }}void PaintWidget::mouseReleaseEvent(QMouseEvent *event){    perm = true;}


// shape.cpp#include "shape.h"Shape::Shape(){}


// line.cpp#include "line.h"Line::Line(){}void Line::paint(QPainter &painter){    painter.drawLine(start, end);}


// rect.cpp#include "rect.h"Rect::Rect(){}void Rect::paint(QPainter &painter){    painter.drawRect(start.x(), start.y(),                     end.x() - start.x(), end.y() - start.y());}