用QT实现一个简易画板

  1. 工程文件:
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    line.cpp \
    main.cpp \
    mainwindow.cpp \
    paintwidget.cpp \
    rect.cpp \
    shape.cpp

HEADERS += \
    line.h \
    mainwindow.h \
    paintwidget.h \
    rect.h \
    shape.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += \
    sketchview.qrc

2.形状类:

shape.h

#ifndef SHAPE_H
#define SHAPE_H

#include 

class Shape
{
public:

    enum Code {
        Line,
        Rect
    };

    Shape();

    virtual void startDraw(QGraphicsSceneMouseEvent * event) = 0;
    virtual void drawing(QGraphicsSceneMouseEvent * event) = 0;
};

#endif // SHAPE_H

shape.cpp

#include "shape.h"

Shape::Shape()
{

}
 

3.直线类:

line.h

#ifndef LINE_H
#define LINE_H

#include 
#include "shape.h"

class Line : public Shape, public QGraphicsLineItem
{
public:
    Line();

    void startDraw(QGraphicsSceneMouseEvent * event);
    void drawing(QGraphicsSceneMouseEvent * event);
};

#endif // LINE_H

line.cpp

#include "line.h"

Line::Line()
{
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
}

void Line::startDraw(QGraphicsSceneMouseEvent * event)
{
    setLine(QLineF(event->scenePos(), event->scenePos()));
}

void Line::drawing(QGraphicsSceneMouseEvent * event)
{
    QLineF newLine(line().p1(), event->scenePos());
    setLine(newLine);
}

4.矩形类:

rect.h

#ifndef RECT_H
#define RECT_H

#include 
#include "shape.h"

class Rect : public Shape, public QGraphicsRectItem
{
public:
    Rect();

    void startDraw(QGraphicsSceneMouseEvent * event);
    void drawing(QGraphicsSceneMouseEvent * event);
};

#endif // RECT_H

rect.cpp

#include "rect.h"

Rect::Rect()
{
    setFlag(QGraphicsItem::ItemIsMovable, true);
    setFlag(QGraphicsItem::ItemIsSelectable, true);
}

void Rect::startDraw(QGraphicsSceneMouseEvent * event)
{
    setRect(QRectF(event->scenePos(), QSizeF(0, 0)));
}

void Rect::drawing(QGraphicsSceneMouseEvent * event)
{
    QRectF r(rect().topLeft(),
             QSizeF(event->scenePos().x() - rect().topLeft().x(), event->scenePos().y() - rect().topLeft().y()));
    setRect(r);
}

5.主窗口:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include "shape.h"

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;

signals:
    void changeCurrentShape(Shape::Code newShape);

private slots:
    void drawLineActionTriggered();
    void drawRectActionTriggered();
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include 
#include 
#include 
#include 
#include 

#include "paintwidget.h"

MainWindow::~MainWindow()
{
    delete ui;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QToolBar *bar = this->addToolBar("Tools");
    QActionGroup *group = new QActionGroup(bar);

    QAction *drawLineAction = new QAction("Line", bar);
    drawLineAction->setIcon(QIcon(":/images/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);
    QAction *drawRectAction = new QAction("Rectangle", bar);
    drawRectAction->setIcon(QIcon(":/images/rectangle.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);
    QGraphicsView *view = new QGraphicsView(paintWidget, this);
    setCentralWidget(view);

    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);
}

6.画布场景类:

paintwidget.h

#ifndef PAINTWIDGET_H
#define PAINTWIDGET_H

#include 

#include "shape.h"
#include "line.h"
#include "rect.h"

class PaintWidget : public QGraphicsScene
{
    Q_OBJECT

public:
    PaintWidget(QWidget *parent = 0);

public slots:
    void setCurrentShape(Shape::Code s)
    {
        if(s != currShapeCode) {
            currShapeCode = s;
        }
    }

protected:
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

private:
    Shape::Code currShapeCode;
    Shape *currItem;
    bool perm;
};

#endif // PAINTWIDGET_H

paintwidget.cpp

#include "paintwidget.h"

PaintWidget::PaintWidget(QWidget *parent)
    : QGraphicsScene((QObject*)parent), currShapeCode(Shape::Line), currItem(NULL), perm(false)
{

}

void PaintWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    switch(currShapeCode)
    {
    case Shape::Line:
    {
        Line *line = new Line;
        currItem = line;
        addItem(line);
        break;
    }
    case Shape::Rect:
    {
        Rect *rect = new Rect;
        currItem = rect;
        addItem(rect);
        break;
    }
    }
    if(currItem) {
        currItem->startDraw(event);
        perm = false;
    }
    QGraphicsScene::mousePressEvent(event);
}

void PaintWidget::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    if(currItem && !perm) {
        currItem->drawing(event);
    }
    QGraphicsScene::mouseMoveEvent(event);
}

void PaintWidget::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    perm = true;
    QGraphicsScene::mouseReleaseEvent(event);
}

7.主程序:

#include "widget.h"

#include 

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

参考链接:

Qt 一个简易画板的实现(Graphics View)_w3cschool

你可能感兴趣的:(qt,开发语言)