首页 > 其他分享 >QML中绘图(1、Canvas 2、QPainter与QML结合)

QML中绘图(1、Canvas 2、QPainter与QML结合)

时间:2022-10-31 21:03:27浏览次数:67  
标签:QColor Canvas QPainter void QML ALPaintedItem event painter 255


 

QML中的Canvas和HTML5中Canvas是一样的,可以参考W3CSchool中的学习方法:​​HTML 5 Canvas 参考手册​


画线、删除线、删除全部实例:

QML中绘图(1、Canvas 2、QPainter与QML结合)_头文件

 

不过,QML中的Canvas不够强大,画线会卡。我们用QPainter来实现画线,用QML来显示就好了,

方式如下:

1、先做好QPainter画线,做我们的类ALPaintedItem:

(1)头文件

#ifndef ALPAINTEDITEM_H
#define ALPAINTEDITEM_H
#include <QQuickPaintedItem>
#include <QPainterPath>
#include <QPainter>
#include <QPointF>
#include <QImage>
#include <QPen>
#include <QBrush>
#include <QColor>
#include <QDebug>
class ALPaintedItem : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(int penWidth READ penWidth WRITE setPenWidth)
Q_PROPERTY(QColor penColor READ penColor WRITE setPenColor)
Q_PROPERTY(bool erasered READ isErasered WRITE setErasered)
public:
ALPaintedItem(QQuickItem *parent = 0);
~ALPaintedItem();
int penWidth() const { return m_penWidth; }
void setPenWidth(int width) { m_penWidth = width; }
QColor penColor() const { return m_brushColor; }
void setPenColor(QColor color) { m_brushColor = color; }
bool isErasered() const{ return m_bErasered; }
void setErasered(bool erasered){ m_bErasered = erasered; }
void paint(QPainter *painter);
Q_INVOKABLE void init();
Q_INVOKABLE void clear();
protected:
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
private:
void drawTmpLine();
void drawBgLine(const QPainterPath &path);
void drawPenStyle(QPainter *painter);
private:
QImage m_bgImage;
QImage m_tempImage;
QColor m_brushColor;
QColor m_eraserColor;
QPointF m_nowPoint;
QPointF m_lastPoint;
QPainterPath *m_pDrawPath;
int m_penWidth;
bool m_bFlag;
bool m_bErasered;
};

#endif // ALPAINTEDITEM_H

 

(2)源文件

#include "alpainteditem.h"
ALPaintedItem::ALPaintedItem(QQuickItem *parent)
: QQuickPaintedItem(parent),
m_brushColor(QColor(0, 0, 0 ,255)),
m_eraserColor(QColor(255,255,255,255)),
m_bFlag(true),
m_bErasered(false),
m_pDrawPath(NULL),
m_penWidth(NULL)
{
setAcceptedMouseButtons(Qt::LeftButton);
}

ALPaintedItem::~ALPaintedItem()
{
}

void ALPaintedItem::paint(QPainter *painter)
{
if(m_bFlag)
painter->drawImage(QRectF(0,0,m_bgImage.width(),m_bgImage.height()),m_bgImage);
else
{
painter->drawImage(QRectF(0,0,m_tempImage.width(),m_tempImage.height()),m_tempImage);
painter->drawImage(QRectF(0,0,m_bgImage.width(),m_bgImage.height()),m_bgImage);
}
}

void ALPaintedItem::init()
{
m_bgImage = QImage(this->width(),this->height(),QImage::Format_ARGB32);
m_tempImage = QImage(this->width(),this->height(),QImage::Format_ARGB32);
m_bgImage.fill(QColor(255,255,255,0));
m_tempImage.fill(QColor(255,255,255,0));
}

void ALPaintedItem::clear()
{
m_bgImage.fill(QColor(255,255,255,0));
m_tempImage.fill(QColor(255,255,255,0));
update();
}

void ALPaintedItem::mousePressEvent(QMouseEvent *event)
{
if(!(event->button() & acceptedMouseButtons()))
{
QQuickPaintedItem::mousePressEvent(event);
}
else{
if(m_pDrawPath == NULL)
{
m_pDrawPath = new QPainterPath();
}
m_pDrawPath->moveTo(event->localPos());
m_nowPoint = event->localPos();
}
}

void ALPaintedItem::mouseMoveEvent(QMouseEvent *event)
{
m_lastPoint = m_nowPoint;
m_nowPoint = event->localPos();
QPointF tmpPoint = m_nowPoint - m_lastPoint;
if(m_pDrawPath == NULL)
{
return;
}
if(qAbs(tmpPoint.x()) > 0 || qAbs(tmpPoint.y()) >0)
{
m_pDrawPath->quadTo(m_lastPoint.x() , m_lastPoint.y() ,(m_nowPoint.x() + m_lastPoint.x())/2,(m_nowPoint.y() + m_lastPoint.y())/2);
m_bFlag = false;
if(m_bErasered)
drawBgLine(*m_pDrawPath);
else
drawTmpLine(); // 临时画
}
QQuickPaintedItem::mouseMoveEvent(event);
}

void ALPaintedItem::mouseReleaseEvent(QMouseEvent *event)
{
if(!(event->button() & acceptedMouseButtons()))
{
QQuickPaintedItem::mousePressEvent(event);
}
else{
if(m_pDrawPath != NULL)
{
m_bFlag = true;
drawBgLine(*m_pDrawPath);
delete m_pDrawPath;
m_pDrawPath = NULL;
}
}
}

void ALPaintedItem::drawTmpLine()
{
QPainter painter(&m_tempImage);
drawPenStyle(&painter);
painter.drawLine(m_lastPoint,m_nowPoint);
qreal rad = this->width()/375.0*170;//点周围范围值
qDebug() << "rad:" << rad;
QRect rect = QRect(m_nowPoint.x() - 5, m_nowPoint.y() - 5,10,10);
update(rect.adjusted(-rad,-rad,+rad,+rad));
}

void ALPaintedItem::drawBgLine(const QPainterPath &path)
{
QPainter painter(&m_bgImage);
drawPenStyle(&painter);
painter.drawPath(path);
m_tempImage.fill(QColor(255,255,255,0));
update();
}

void ALPaintedItem::drawPenStyle(QPainter *painter)
{
painter->setRenderHint(QPainter::Antialiasing);
QBrush brush(m_brushColor, Qt::SolidPattern);
if(m_bErasered)
{
painter->setCompositionMode(QPainter::CompositionMode_Clear);
painter->setPen(QPen(brush, 5*m_penWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
}
else
{
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
painter->setPen(QPen(brush, m_penWidth, Qt::SolidLine, Qt::RoundCap,Qt::RoundJoin));
}
painter->setBrush(Qt::NoBrush);
}

 

2、注册这个类

    qmlRegisterType<ALPaintedItem>("ALPaintedItem", 1, 0, "ALPaintedItem");

 

3、QML中调用

import QtQuick 2.5
import ALPaintedItem 1.0

Rectangle {
id:photoMarkedRoot
color: "transparent"
property alias painter: painter

Component.onCompleted: {
painter.penWidth = initHeight/647.0*3
painter.penColor = "red"
painter.init()
}

ALPaintedItem {
id: painter;
width: photoMarkedRoot.width
height: photoMarkedRoot.height
onWidthChanged: {
painter.init()
}
onHeightChanged: {
painter.init()
}
}
}

 

标签:QColor,Canvas,QPainter,void,QML,ALPaintedItem,event,painter,255
From: https://blog.51cto.com/u_15854865/5811267

相关文章

  • Qt5气泡式聊天框——QListWidget+QPainter实现
    文章目录​​1、简介​​​​2、效果图​​​​3、实现原理​​​​4、核心代码​​​​4.1、头文件​​​​4.2、源文件​​​​5、代码分享​​​​5.1、Github​​​​5.......
  • QML与QWidget简单的联合使用(QQuickWidget衔接)
    如果碰到这种情况,可能软件整体并不复杂也不需要太多炫酷的效果,此时我们可能选择QWidget体系来做。但是,可能某个小部件又非常需要炫酷的效果,QWidget并不是我们此时想要的,可以......
  • QML 怎么调用 C++ 中的内容?
    以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「englyf」https://mp.weixin.qq.com/s/z_JlmNe6cYldNf11Oad_JQ先说明一下测试环境编译器:vs2017x64开发......
  • js canvas
      <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"......
  • vue canvas 线上签名
    <template> <divid="box">   <divclass="main"id='main'>     <canvasref="saveCanvas"width="500"height="400"@mousedown="ctxDown($event)"@mousem......
  • Canvas基本绘制操作
    Canvas绘制线条中常见的属性和方法属性(方法)说明linwWidth定义线条的宽度,属性值为整数,默认是1,默认单位是pxlineCap定义线条开始和结尾处的线帽样式,属性值:butt(默认值,无线帽)......
  • Canvas实现多叶草效果的封装
    四叶草的效果:想要实现四叶草以及多叶草的效果,需要了解四叶草的构成。想要在网页上作图,则需要添加画布Canvas,而四叶草是由曲线构成的,可以使用贝塞尔曲线来绘制,HTML代码:<can......
  • HTML5 Canvas基础概念(一)
    Canvas基础知识:Canvas属于行内元素,使用Canvas绘制图形步骤:1、获取Canvas对象2、获取上下文环境对象context。3、开始绘制图形在Canvas对象中常用属性属性说明widthCanvas的......
  • vue.js+canvas实现随机验证码
    登录注册啥的,不需要下载插件,上图:<template><divclass="about"><p>当前验证码:{{codeStr}}</p><canvasid="canvas"width="100"height="43"@click="cr......
  • 前端绘图方式Canvas和SVG的区别
    前端绘图方式Canvas和SVG的区别Canvas和SVG是html5中支持2种可视化技术,都是可以在画布上绘制图形和放入图片。下面来介绍和分析一下他们。一.Canvas和SVG简介1.什么是......