qml绘图的三种方式

QQ:609162385
qml绘图的三种方式
1,继承QQuickPaintedItem重写void paint(QPainter *painter);
在这里插入图片描述

#include "PaintedItem.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
#include <QColor>
#include <QDebug>

PaintedItem::PaintedItem(QQuickItem *parent)
    : QQuickPaintedItem(parent)
    , m_element(0)
    , m_bEnabled(true)
    , m_bPressed(false)
    , m_bMoved(false)
    , m_pen(Qt::black)
{
    setAcceptedMouseButtons(Qt::LeftButton);
}

PaintedItem::~PaintedItem()
{
    purgePaintElements();
}

void PaintedItem::clear()
{
    purgePaintElements();
    update();
}

void PaintedItem::undo()
{
    if(m_elements.size())
    {
        delete m_elements.takeLast();
        update();
    }
}

void PaintedItem::paint(QPainter *painter)
{
    painter->setRenderHint(QPainter::Antialiasing);

    int size = m_elements.size();
    ElementGroup *element;
    for(int i = 0; i < size; ++i)
    {
        element = m_elements.at(i);
        painter->setPen(element->m_pen);
        painter->drawLines(element->m_lines);
    }
}

void PaintedItem::mousePressEvent(QMouseEvent *event)
{
    m_bMoved = false;
    if(!m_bEnabled || !(event->button() & acceptedMouseButtons()))
    {
        QQuickPaintedItem::mousePressEvent(event);
    }
    else
    {
        m_bPressed = true;
        m_element = new ElementGroup(m_pen);
        m_elements.append(m_element);
        m_lastPoint = event->localPos();
        event->setAccepted(true);
    }
}

void PaintedItem::mouseMoveEvent(QMouseEvent *event)
{
    if(!m_bEnabled || !m_bPressed || !m_element)
    {
        QQuickPaintedItem::mousePressEvent(event);
    }
    else
    {
        //qDebug() << "mouse move";
        m_element->m_lines.append(QLineF(m_lastPoint, event->localPos()));
        m_lastPoint = event->localPos();
        update();
    }
}

void PaintedItem::mouseReleaseEvent(QMouseEvent *event)
{
    if(!m_element || !m_bEnabled || !(event->button() & acceptedMouseButtons()))
    {
        QQuickPaintedItem::mousePressEvent(event);
    }
    else
    {
        //qDebug() << "mouse released";
        m_bPressed = false;
        m_bMoved = false;
        m_element->m_lines.append(QLineF(m_lastPoint, event->localPos()));
        update();
    }
}

void PaintedItem::purgePaintElements()
{
    int size = m_elements.size();
    if(size > 0)
    {
        for(int i = 0; i < size; ++i)
        {
            delete m_elements.at(i);
        }
        m_elements.clear();
    }
    m_element = 0;
}

效果如下:在这里插入图片描述

2,继承QQuickItem重写QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);配合QSGNode实现:

#include "ordinateitem.h"
#include <QSGGeometryNode>
#include <QSGFlatColorMaterial>
#include <QDebug>

namespace UtAbCapb {

OrdinateItem::OrdinateItem()
{
    setFlag(ItemHasContents, true);
    this->init();
}

void OrdinateItem::init()
{
    m_scale_vp = LeftVP;
    m_line_width = 1;
    m_line_color = "#C5AD63";
    m_ruler_count = 35;
}

int OrdinateItem::scaleViewPostion()
{
    return m_scale_vp;
}

void OrdinateItem::setScaleViewPostion(int vp)
{
    m_scale_vp = vp;
}

int OrdinateItem::lineWidth()
{
    return m_line_width;
}

void OrdinateItem::setLineWidth(int width)
{
    m_line_width = width;
}

QString OrdinateItem::lineColor()
{
    return m_line_color;
}

void OrdinateItem::setLineColor(QString color)
{
    m_line_color = color;
}

int OrdinateItem::rulerTotal()
{
    return m_ruler_count;
}

void OrdinateItem::setRulerTotal(int count)
{
    if(count>=10 && count<120){
        m_ruler_count = count;
        update();
    }
}

QSGNode *OrdinateItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
    float max_x = (width()>30)? 20 : width();
    float max_y = height();
    float rulerUnit = (max_y-10)/m_ruler_count;
    float scal_h = max_x;
    float scal_m = max_x*0.8;
    float scal_l = max_x*0.5;
    int totalCount = m_ruler_count*2 + 4;

    QSGGeometryNode *node = 0;
    node = static_cast<QSGGeometryNode *>(oldNode);
    QSGGeometry *geometry;
    QSGFlatColorMaterial *material;
    if(!node) {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), totalCount);
        geometry->setDrawingMode(GL_LINES);
        geometry->setLineWidth(m_line_width);
        material = new QSGFlatColorMaterial;
        material->setColor(QColor(m_line_color));
        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry);
        node->setMaterial(material);
        node->setFlag(QSGNode::OwnsMaterial);
    } else {
        geometry = node->geometry();
        material = static_cast<QSGFlatColorMaterial *>(node->material());
        geometry->allocate(totalCount);
    }

    QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
    int max = (m_scale_vp == LeftVP)? max_x : 0;
    vertices[0].set(max, 0);
    vertices[1].set(max, max_y);
    float x0=0;
    float y0=max_y;
    float x;
    float y;
    int cout =1;
    for(int i=0;i<=m_ruler_count;i++){
        int itype = (i%5==0 && i%10==0)? 0 :((i%5==0 && i%10!=0)? 1 : 2); //0:max,1:mid,2:min
        switch (itype) {
        case 0:
            x0 = 0;
            x = scal_h;
            y = y0;
            break;
        case 1:
            x0 = (m_scale_vp == LeftVP)? scal_h*0.2 : 0;
            x = (m_scale_vp == LeftVP)? scal_h : scal_m;
            y = y0;
            break;
        case 2:
            x0 = (m_scale_vp == LeftVP)? scal_l : 0;
            x = (m_scale_vp == LeftVP)? scal_h : scal_l;
            y = y0;
            break;
        default:
            break;
        }
        vertices[++cout].set(x0, y0);
        vertices[++cout].set(x, y);
        y0 = y0 - rulerUnit;
    }
    node->markDirty(QSGNode::DirtyGeometry);
    return node;
}
}

在这里插入图片描述
3,Canvas

import QtQuick 2.1
import QtQuick.Window 2.1

import "qrc:/Canvas1/qml/RES/"

Window {
    visible: true
    width: imgBg.width*2
    height: imgBg.height
    title: qsTr("qmlPainterCanvas")

    property var _listData:[0,50,0,70,10,0,-60,0,50,0,30,0,25,-80,0,20,0,70,0,20,0]
    property var _list: new Array
    property int marginY: 200
    property int marginX: 100
    property int spacing: 15
    property int currentIndex: 0

    property int maxLen: _listData.length

    Component.onCompleted: {
    }

    Image{
        id: imgBg
        source: "qrc:/BGMain.png"
    }

    Item{
        id: itemCanvas
        anchors.fill: parent

        transform: Rotation{
            axis.x: 0
            axis.y: 1
            axis.z: 1

            origin.x: 0
            origin.y: itemCanvas.height/2

            angle: 5
        }

        Canvas {
            id: canvas
            anchors.fill: parent

            property real lastX: 0
            property real lastY: 0

            onPaint: {
                //0,0 在左上角
                var ctx = getContext('2d')

                ctx.clearRect(0, 0, canvas.width, canvas.height)

                //基线
                ctx.lineWidth = 1.0
                ctx.strokeStyle = "#bdfcff"
                ctx.beginPath()
                ctx.moveTo(marginX, canvas.height - marginY)
                ctx.lineTo(300+marginX, canvas.height - marginY)
                ctx.stroke()

                ctx.lineWidth = 5.0
                ctx.strokeStyle = "#bdfcff"
                ctx.lineJoin = "miter"   //miter, bevel, round
                ctx.lineCap = "butt"        //butt,round,square
                ctx.beginPath()
                ctx.shadowColor = "#bdfcff"
                ctx.shadowBlur = 15
                ctx.shadowOffsetX = -5
                ctx.shadowOffsetY = -5

                //                console.log(_list.length)
                for(var i=0; i<_list.length; i++){

                    var x1 = i*spacing + marginX + (maxLen-_list.length)*spacing
                    var y1 = canvas.height - _list[i] - marginY

                    if(i == 0){
                        ctx.moveTo(x1, y1)
                    }
                    else if(i == _list.length-1){
                        ctx.lineTo(x1, y1)
                        ctx.stroke()
                    }
                    else{
                        ctx.lineTo(x1, y1)
                    }

                    lastX = x1
                    lastY = y1

                }
            }
        }

    }

    Timer{
        id: timer
        interval: 1000
        running: true
        repeat: true
        onTriggered: {
            addPoint(_listData[currentIndex])
            currentIndex++
            if(currentIndex>maxLen-1){
                currentIndex = 0
            }
        }
    }

    function addPoint(num){
        _list.push(num)
        if(_list.length>maxLen){
            _list.splice(0,1)
        }
        canvas.requestPaint()
    }

    Rectangle{
        id:rec
        x:imgBg.width
        y:0
        width:imgBg.width
        height: imgBg.height
        color: "gray"
        Canvas{
            x:0
            y:0
            id:canvas_two
            width: imgBg.width
            height: imgBg.height
            property real lastX
            property real lastY
            contextType: "2d"
            visible: true
            onPaint: {//绘图事件的响应
                context.lineWidth=1.0;//线的宽度
                context.strokeStyle="red";//线的颜色
                context.fillStyle="white";//填充颜色
                context.beginPath();//开始
                context.moveTo(lastX, lastY)//移动到指定位置
                lastX = area.mouseX
                lastY = area.mouseY
                context.lineTo(lastX, lastY)//划线到指定位置
                context.stroke();//背景执行
            }
            MouseArea {
                id: area
                anchors.fill: parent//屏蔽父窗口的点击事件
                onPressed: {
                    canvas_two.lastX = mouseX//鼠标位置
                    canvas_two.lastY = mouseY
                }
                onPositionChanged: {//位置改变事件
                    canvas_two.requestPaint()//重绘
                }
            }
        }
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cqltbe131421/article/details/83147861
今日推荐