【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://devbean.blog.51cto.com/448512/243546
说实话,本来我是没有打算放一个很大的例子的,一则比较复杂,二来或许需要很多次才能说得完。不过,现在已经说完了绘图部分,所以计划还是上一个这样的例子。这里我会只做出一个简单的画板程序,大体上就是能够画直线和矩形吧。这样,我计划分成两种实现,一是使用普通的QWidget作为画板,第二则是使用Graphcis View Framework来实现。因为前面有朋友说不大明白Graphics View的相关内容,所以计划如此。
 
好了,现在先来看看我们的主体框架。我们的框架还是使用Qt Creator创建一个Gui Application工程。
 
简单的main()函数就不再赘述了,这里首先来看MainWindow。顺便说一下,我一般不会使用ui文件,所以这些内容都是手写的。首先先来看看最终的运行结果:
 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
或许很简单,但是至少我们能够把前面所说的各种知识串连起来,这也就达到目的了。
 
现在先来看看MainWindow的代码:
 
mainwindow.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef MAINWINDOW_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define MAINWINDOW_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QtGui> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "paintwidget.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class MainWindow : public QMainWindow 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Q_OBJECT 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        MainWindow(QWidget *parent = 0); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框signals: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void changeCurrentShape(Shape::Code newShape); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框private slots: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void drawLineActionTriggered(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void drawRectActionTriggered(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // MAINWINDOW_H
 
mainwindow.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "mainwindow.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框MainWindow::MainWindow(QWidget *parent) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        : QMainWindow(parent) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QToolBar *bar = this->addToolBar("Tools"); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QActionGroup *group = new QActionGroup(bar); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QAction *drawLineAction = new QAction("Line", bar); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setIcon(QIcon(":/line.png")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setToolTip(tr("Draw a line.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setStatusTip(tr("Draw a line.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setCheckable(true); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setChecked(true); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        group->addAction(drawLineAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        bar->addAction(drawLineAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QAction *drawRectAction = new QAction("Rectangle", bar); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setIcon(QIcon(":/rect.png")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setToolTip(tr("Draw a rectangle.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setStatusTip(tr("Draw a rectangle.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setCheckable(true); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        group->addAction(drawRectAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        bar->addAction(drawRectAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QLabel *statusMsg = new QLabel; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        statusBar()->addWidget(statusMsg); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        PaintWidget *paintWidget = new PaintWidget(this); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        setCentralWidget(paintWidget); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        connect(drawLineAction, SIGNAL(triggered()), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        this, SLOT(drawLineActionTriggered())); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        connect(drawRectAction, SIGNAL(triggered()), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        this, SLOT(drawRectActionTriggered())); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        connect(this, SIGNAL(changeCurrentShape(Shape::Code)), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        paintWidget, SLOT(setCurrentShape(Shape::Code))); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void MainWindow::drawLineActionTriggered() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        emit changeCurrentShape(Shape::Line); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void MainWindow::drawRectActionTriggered() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        emit changeCurrentShape(Shape::Rect); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
应该说,从以往的学习中可以看出,这里的代码没有什么奇怪的了。我们在MainWindow类里面声明了一个信号,changeCurrentShape(Shape::Code),用于按钮按下后通知画图板。注意,QActio的triggered()信号是没有参数的,因此,我们需要在QAction的槽函数中重新emit我们自己定义的信号。构造函数里面创建了两个QAction,一个是drawLineAction,一个是drawRectAction,分别用于绘制直线和矩形。MainWindow的中心组件是PainWidget,也就是我们的画图板。下面来看看PaintWidget类:
 
paintwidget.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef PAINTWIDGET_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define PAINTWIDGET_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QtGui> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QDebug> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "line.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "rect.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class PaintWidget : public QWidget 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Q_OBJECT 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        PaintWidget(QWidget *parent = 0); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public slots: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void setCurrentShape(Shape::Code s) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                if(s != currShapeCode) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        currShapeCode = s; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框protected
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void paintEvent(QPaintEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void mousePressEvent(QMouseEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void mouseMoveEvent(QMouseEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void mouseReleaseEvent(QMouseEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框private
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Shape::Code currShapeCode; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Shape *shape; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        bool perm; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QList<Shape*> shapeList; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // PAINTWIDGET_H 
 
paintwidget.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "paintwidget.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框PaintWidget::PaintWidget(QWidget *parent) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        : QWidget(parent), currShapeCode(Shape::Line), shape(NULL), perm(false
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::paintEvent(QPaintEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPainter painter(this); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.setBrush(Qt::white); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.drawRect(0, 0, size().width(), size().height()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        foreach(Shape * shape, shapeList) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->paint(painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        if(shape) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->paint(painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::mousePressEvent(QMouseEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        switch(currShapeCode) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        case Shape::Line: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        shape = new Line; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        break
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        case Shape::Rect: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        shape = new Rect; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        break
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        if(shape != NULL) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                perm = false
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shapeList<<shape; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->setStart(event->pos()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->setEnd(event->pos()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::mouseMoveEvent(QMouseEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        if(shape && !perm) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->setEnd(event->pos()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                update(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::mouseReleaseEvent(QMouseEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        perm = true
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
PaintWidget类定义了一个slot,用于接收改变后的新的ShapeCode。最主要的是,PaintWidget重定义了三个关于鼠标的事件:mousePressEvent,mouseMoveEvent和mouseReleaseEvent。
 
我们来想象一下如何绘制一个图形:图形的绘制与鼠标操作息息相关。以画直线为例,首先我们需要按下鼠标,确定直线的第一个点,所以在mousePressEvent里面,我们让shape保存下start点。然后在鼠标按下的状态下移动鼠标,此时,直线就会发生变化,实际上是直线的终止点在随着鼠标移动,所以在mouseMoveEvent中我们让shape保存下end点,然后调用update()函数,这个函数会自动调用paintEvent()函数,显示出我们绘制的内容。最后,当鼠标松开时,图形绘制完毕,我们将一个标志位置为true,此时说明这个图形绘制完毕。
 
为了保存我们曾经画下的图形,我们使用了一个List。每次按下鼠标时,都会把图形存入这个List。可以看到,我们在paintEvent()函数中使用了foreach遍历了这个List,绘制出历史图形。foreach是Qt提供的一个宏,用于遍历集合中的元素。
 
最后我们来看看Shape类。
 
shape.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef SHAPE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define SHAPE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QtGui> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class Shape 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        enum Code { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                Line, 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                Rect 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        }; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Shape(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void setStart(QPoint s) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                start = s; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void setEnd(QPoint e) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                end = e; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint startPoint() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                return start; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint endPoint() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                return end; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void virtual paint(QPainter & painter) = 0; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框protected
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint start; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint end; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // SHAPE_H 
 
shape.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框Shape::Shape() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
Shape类最重要的就是保存了start和end两个点。为什么只要这两个点呢?因为我们要绘制的是直线和矩形。对于直线来说,有了两个点就可以确定这条直线,对于矩形来说,有了两个点作为左上角的点和右下角的点也可以确定这个矩形,因此我们只要保存两个点,就足够保存这两种图形的位置和大小的信息。paint()函数是Shape类的一个纯虚函数,子类都必须实现这个函数。我们现在有两个子类:Line和Rect,分别定义如下:
 
line.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef LINE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define LINE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class Line : public Shape 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Line(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void paint(QPainter &painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // LINE_H 
 
line.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "line.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框Line::Line() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void Line::paint(QPainter &painter) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.drawLine(start, end); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
rect.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef RECT_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define RECT_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class Rect : public Shape 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Rect(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void paint(QPainter &painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // RECT_H 
 
rect.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "rect.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框Rect::Rect() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void Rect::paint(QPainter &painter) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.drawRect(start.x(), start.y(), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                                         end.x() - start.x(), end.y() - start.y()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
使用paint()函数,根据两个点的数据,Line和Rect都可以绘制出它们自身来。此时就可以看出,我们之所以要建立一个Shape作为父类,因为这两个类有几乎完全相似的数据对象,并且从语义上来说,Line、Rect与Shape也完全是一个is-a的关系。如果你想要添加颜色等的信息,完全可以在Shape类进行记录。这也就是类层次结构的好处。

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://devbean.blog.51cto.com/448512/243546
说实话,本来我是没有打算放一个很大的例子的,一则比较复杂,二来或许需要很多次才能说得完。不过,现在已经说完了绘图部分,所以计划还是上一个这样的例子。这里我会只做出一个简单的画板程序,大体上就是能够画直线和矩形吧。这样,我计划分成两种实现,一是使用普通的QWidget作为画板,第二则是使用Graphcis View Framework来实现。因为前面有朋友说不大明白Graphics View的相关内容,所以计划如此。
 
好了,现在先来看看我们的主体框架。我们的框架还是使用Qt Creator创建一个Gui Application工程。
 
简单的main()函数就不再赘述了,这里首先来看MainWindow。顺便说一下,我一般不会使用ui文件,所以这些内容都是手写的。首先先来看看最终的运行结果:
 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
或许很简单,但是至少我们能够把前面所说的各种知识串连起来,这也就达到目的了。
 
现在先来看看MainWindow的代码:
 
mainwindow.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef MAINWINDOW_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define MAINWINDOW_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QtGui> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "paintwidget.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class MainWindow : public QMainWindow 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Q_OBJECT 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        MainWindow(QWidget *parent = 0); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框signals: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void changeCurrentShape(Shape::Code newShape); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框private slots: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void drawLineActionTriggered(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void drawRectActionTriggered(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // MAINWINDOW_H
 
mainwindow.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "mainwindow.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框MainWindow::MainWindow(QWidget *parent) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        : QMainWindow(parent) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QToolBar *bar = this->addToolBar("Tools"); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QActionGroup *group = new QActionGroup(bar); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QAction *drawLineAction = new QAction("Line", bar); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setIcon(QIcon(":/line.png")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setToolTip(tr("Draw a line.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setStatusTip(tr("Draw a line.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setCheckable(true); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawLineAction->setChecked(true); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        group->addAction(drawLineAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        bar->addAction(drawLineAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QAction *drawRectAction = new QAction("Rectangle", bar); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setIcon(QIcon(":/rect.png")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setToolTip(tr("Draw a rectangle.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setStatusTip(tr("Draw a rectangle.")); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        drawRectAction->setCheckable(true); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        group->addAction(drawRectAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        bar->addAction(drawRectAction); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QLabel *statusMsg = new QLabel; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        statusBar()->addWidget(statusMsg); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        PaintWidget *paintWidget = new PaintWidget(this); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        setCentralWidget(paintWidget); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        connect(drawLineAction, SIGNAL(triggered()), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        this, SLOT(drawLineActionTriggered())); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        connect(drawRectAction, SIGNAL(triggered()), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        this, SLOT(drawRectActionTriggered())); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        connect(this, SIGNAL(changeCurrentShape(Shape::Code)), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        paintWidget, SLOT(setCurrentShape(Shape::Code))); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void MainWindow::drawLineActionTriggered() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        emit changeCurrentShape(Shape::Line); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void MainWindow::drawRectActionTriggered() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        emit changeCurrentShape(Shape::Rect); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
应该说,从以往的学习中可以看出,这里的代码没有什么奇怪的了。我们在MainWindow类里面声明了一个信号,changeCurrentShape(Shape::Code),用于按钮按下后通知画图板。注意,QActio的triggered()信号是没有参数的,因此,我们需要在QAction的槽函数中重新emit我们自己定义的信号。构造函数里面创建了两个QAction,一个是drawLineAction,一个是drawRectAction,分别用于绘制直线和矩形。MainWindow的中心组件是PainWidget,也就是我们的画图板。下面来看看PaintWidget类:
 
paintwidget.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef PAINTWIDGET_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define PAINTWIDGET_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QtGui> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QDebug> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "line.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "rect.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class PaintWidget : public QWidget 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Q_OBJECT 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        PaintWidget(QWidget *parent = 0); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public slots: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void setCurrentShape(Shape::Code s) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                if(s != currShapeCode) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        currShapeCode = s; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框protected
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void paintEvent(QPaintEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void mousePressEvent(QMouseEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void mouseMoveEvent(QMouseEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void mouseReleaseEvent(QMouseEvent *event); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框private
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Shape::Code currShapeCode; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Shape *shape; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        bool perm; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QList<Shape*> shapeList; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // PAINTWIDGET_H 
 
paintwidget.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "paintwidget.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框PaintWidget::PaintWidget(QWidget *parent) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        : QWidget(parent), currShapeCode(Shape::Line), shape(NULL), perm(false
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::paintEvent(QPaintEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPainter painter(this); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.setBrush(Qt::white); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.drawRect(0, 0, size().width(), size().height()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        foreach(Shape * shape, shapeList) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->paint(painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        if(shape) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->paint(painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::mousePressEvent(QMouseEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        switch(currShapeCode) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        case Shape::Line: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        shape = new Line; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        break
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        case Shape::Rect: 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        shape = new Rect; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                        break
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        if(shape != NULL) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                perm = false
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shapeList<<shape; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->setStart(event->pos()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->setEnd(event->pos()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::mouseMoveEvent(QMouseEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        if(shape && !perm) { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                shape->setEnd(event->pos()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                update(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void PaintWidget::mouseReleaseEvent(QMouseEvent *event
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        perm = true
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
PaintWidget类定义了一个slot,用于接收改变后的新的ShapeCode。最主要的是,PaintWidget重定义了三个关于鼠标的事件:mousePressEvent,mouseMoveEvent和mouseReleaseEvent。
 
我们来想象一下如何绘制一个图形:图形的绘制与鼠标操作息息相关。以画直线为例,首先我们需要按下鼠标,确定直线的第一个点,所以在mousePressEvent里面,我们让shape保存下start点。然后在鼠标按下的状态下移动鼠标,此时,直线就会发生变化,实际上是直线的终止点在随着鼠标移动,所以在mouseMoveEvent中我们让shape保存下end点,然后调用update()函数,这个函数会自动调用paintEvent()函数,显示出我们绘制的内容。最后,当鼠标松开时,图形绘制完毕,我们将一个标志位置为true,此时说明这个图形绘制完毕。
 
为了保存我们曾经画下的图形,我们使用了一个List。每次按下鼠标时,都会把图形存入这个List。可以看到,我们在paintEvent()函数中使用了foreach遍历了这个List,绘制出历史图形。foreach是Qt提供的一个宏,用于遍历集合中的元素。
 
最后我们来看看Shape类。
 
shape.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef SHAPE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define SHAPE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include <QtGui> 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class Shape 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        enum Code { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                Line, 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                Rect 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        }; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Shape(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void setStart(QPoint s) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                start = s; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void setEnd(QPoint e) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                end = e; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint startPoint() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                return start; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint endPoint() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        { 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                return end; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        } 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void virtual paint(QPainter & painter) = 0; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框protected
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint start; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        QPoint end; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // SHAPE_H 
 
shape.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框Shape::Shape() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
Shape类最重要的就是保存了start和end两个点。为什么只要这两个点呢?因为我们要绘制的是直线和矩形。对于直线来说,有了两个点就可以确定这条直线,对于矩形来说,有了两个点作为左上角的点和右下角的点也可以确定这个矩形,因此我们只要保存两个点,就足够保存这两种图形的位置和大小的信息。paint()函数是Shape类的一个纯虚函数,子类都必须实现这个函数。我们现在有两个子类:Line和Rect,分别定义如下:
 
line.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef LINE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define LINE_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class Line : public Shape 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Line(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void paint(QPainter &painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // LINE_H 
 
line.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "line.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框Line::Line() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void Line::paint(QPainter &painter) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.drawLine(start, end); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
rect.h
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#ifndef RECT_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#define RECT_H 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "shape.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框class Rect : public Shape 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框public
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        Rect(); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        void paint(QPainter &painter); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框}; 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#endif // RECT_H 
 
rect.cpp
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框#include "rect.h" 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框Rect::Rect() 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框void Rect::paint(QPainter &painter) 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框        painter.drawRect(start.x(), start.y(), 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框                                         end.x() - start.x(), end.y() - start.y()); 
【Qt开发】Qt在QLabel(QWidget)鼠标绘制直线和矩形框
 
使用paint()函数,根据两个点的数据,Line和Rect都可以绘制出它们自身来。此时就可以看出,我们之所以要建立一个Shape作为父类,因为这两个类有几乎完全相似的数据对象,并且从语义上来说,Line、Rect与Shape也完全是一个is-a的关系。如果你想要添加颜色等的信息,完全可以在Shape类进行记录。这也就是类层次结构的好处。