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