QT涂鸦窗口/写字板

在QT中要实现一个涂鸦窗口是非常简单的事情,先将项目早期用到的涂鸦窗口抽取出来做成一个通用的模型,方便以后的项目中可以使用。

效果图:
这里写图片描述

实现功能:
1、鼠标按住随意划线;
2、可设置线宽,样式,颜色;
3、可设置背景图片;
4、可清除所有绘制;
5、可保存涂鸦图片。

涂鸦窗口类头文件实现:

#ifndef DOODLEWIDGET_H
#define DOODLEWIDGET_H

#include <QWidget>
#include <QPaintEvent>
#include <QMouseEvent>
#include <QIODevice>

class DoodleWidgetPrivate;

class DoodleWidget : public QWidget
{
    Q_OBJECT
    Q_DECLARE_PRIVATE(DoodleWidget)
public:
    explicit DoodleWidget(QWidget *parent = 0, const QSize& doodleSize = QSize(800, 600));
    virtual ~DoodleWidget();

    // set background image
    bool setBackgroundImage(const QString& path, bool bStretch = false);

    //save cache image to file / device IO
    bool saveImage(const QString& path, const QString& ext = "JPEG");
    bool saveImage(QIODevice* device, const QString& ext = "JPEG");

    //set cache image size
    void setDoodleSize(const QSize& size);

    //set pen width,color,style
    void setPenStyle(int width = 3, Qt::PenStyle ps = Qt::SolidLine, const QColor& qc = Qt::black);

signals:

public slots:
    void changePenWidth(int width);
    void changePenStyle(Qt::PenStyle ps);
    void changePenColor(const QColor& cr);
    void clearDoodle();

protected:
    void paintEvent(QPaintEvent* event);
    void mousePressEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);

private:
    DoodleWidgetPrivate* d_ptr = nullptr;
};

#endif // DoodleWIDGET_H

涂鸦窗口实现文件:

#include "doodlewidget.h"
#include <QPainter>

class DoodleWidgetPrivate
{
    Q_DECLARE_PUBLIC(DoodleWidget)
public:
    DoodleWidgetPrivate(DoodleWidget* q, const QSize& doodleSize);
    ~DoodleWidgetPrivate();
    void initCache();
    void drawLines(const QPoint& ptBegin, const QPoint& ptEnd);

public:
    DoodleWidget* q_ptr = nullptr;
    QPixmap* image = nullptr;
    QPainter* painter = nullptr;
    QPen pen;
    QPoint lastCursorPos;
    bool bLeftMousePressed = false;
};

DoodleWidgetPrivate::DoodleWidgetPrivate(DoodleWidget* q, const QSize& doodleSize)
    : q_ptr(q), image(new QPixmap(doodleSize)), painter(new QPainter(image))
{
    painter->setRenderHint(QPainter::HighQualityAntialiasing, true);
    initCache();
}

DoodleWidgetPrivate::~DoodleWidgetPrivate()
{
    delete painter;
    delete image;
}

void DoodleWidgetPrivate::initCache()
{
    Q_Q(DoodleWidget);
    painter->fillRect(0, 0, image->width(), image->height(), Qt::white);
    q->update();
}

void DoodleWidgetPrivate::drawLines(const QPoint &ptBegin, const QPoint &ptEnd)
{
    Q_Q(DoodleWidget);
    painter->drawLine(ptBegin, ptEnd);
    q->update();
}

DoodleWidget::DoodleWidget(QWidget *parent, const QSize &doodleSize)
    : QWidget(parent), d_ptr(new DoodleWidgetPrivate(this, doodleSize))
{
    setCursor(Qt::CrossCursor);
    setMouseTracking(true);
    setPenStyle();
}

DoodleWidget::~DoodleWidget()
{
    delete d_ptr;
}

bool DoodleWidget::setBackgroundImage(const QString &path, bool bStretch)
{
    Q_D(DoodleWidget);
    QPixmap tmp;
    if (!tmp.load(path)) {
        return false;
    }
    if (bStretch) {
        d->painter->drawPixmap(0, 0, d->image->width(), d->image->height(), tmp);
    }
    else {
        d->painter->drawPixmap(0, 0, tmp);
    }
    return true;
}

bool DoodleWidget::saveImage(const QString &path, const QString &ext)
{
    Q_D(DoodleWidget);
    return d->image->save(path, 
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值