用qml画坐标

最近在做一个关于坐标的界面,

花了两天用qml画出来了,这里贴出来分享一下;

c++类OrdinateItem

ordinateItem.h文件

#ifndef ORDINATEITEMS_H
#define ORDINATEITEMS_H

#include <QQuickItem>

namespace UtAbCapb {

class OrdinateItem : public QQuickItem//这里必须继承QQuickItem,因为要用到它的很多属性
{
    Q_OBJECT
    Q_PROPERTY(int scaleViewPostion  READ scaleViewPostion WRITE setScaleViewPostion NOTIFY scaleViewPostionChanged)
    Q_PROPERTY(int      lineWidth    READ lineWidth  WRITE setLineWidth  NOTIFY lineWidthChanged)
    Q_PROPERTY(QString  lineColor    READ lineColor  WRITE setLineColor  NOTIFY lineColorChanged)
    Q_PROPERTY(int      rulerTotal   READ rulerTotal WRITE setRulerTotal NOTIFY rulerTotalChanged)

    enum scaleVP{
        RightVP=0,
        LeftVP
    };
public:
    OrdinateItem();//构造

private:
    void init();//初始化
public:
    int     scaleViewPostion();             // 刻度显示位置(0:默认左边,1:右边)
    void    setScaleViewPostion(int vp);    //设置刻度显示位置
    int     lineWidth();                    // 画线线宽(默认3)
    void    setLineWidth(int width);        //设置线宽
    QString lineColor();                    // 画线颜色
    void    setLineColor(QString color);    //设置画线颜色
    int     rulerTotal();                   // 总刻度数(默认4)
    void    setRulerTotal(int count);       //设置刻度数

    QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);//更新节点

signals:
    void scaleViewPostionChanged();    //刻度显示位置变化信号
    void lineWidthChanged();  //线宽变化
    void lineColorChanged();  //线颜色变化
    void rulerTotalChanged(); //刻度总是变化
    void rulerUnitChanged(); //刻度初始位置信号
public slots:

private:
    int     m_scale_vp;         // 刻度显示位置
    int     m_line_width;       // 线宽
    QString m_line_color;       // 线颜色
    int     m_ruler_count;      // 刻度大小
};

}
#endif // ORDINATEITEMS_H

ordinateItem.cpp文件

 

#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;//纵坐标刻度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();//定义获取宽度,这里获取的是qml中设定的宽度
    float max_y = height();//获取高度因为继承了QQuickItem
    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,用于场景图中的所有渲染内容
    node = static_cast<QSGGeometryNode *>(oldNode);
    QSGGeometry *geometry;//定义geometry,为图形提供低级存储
    QSGFlatColorMaterial *material;//定义material,提供了一种在场景图中绘制纯色几何图形的方法
    if(!node) {
        node = new QSGGeometryNode;
        geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), totalCount);//默认2d绘图。创建一个没有几何和材质的新的几何节点
        geometry->setDrawingMode(GL_LINES);//绘图模式,GL画线
        geometry->setLineWidth(m_line_width);//设置线宽
        material = new QSGFlatColorMaterial;//实例
        material->setColor(QColor(m_line_color));//设置颜色
        node->setGeometry(geometry);//将geometry添加到node
        node->setFlag(QSGNode::OwnsGeometry);//
        node->setMaterial(material);//将此几何节点的材质设置为material
    } else {
        geometry = node->geometry();
        material = static_cast<QSGFlatColorMaterial *>(node->material());
        geometry->allocate(totalCount);
    }
    //定义vertices,获取的是geometry,2D的顶点数据指针
    QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
    int max = (m_scale_vp == LeftVP)? max_x : 0;//显示的位置
    vertices[0].set(max, 0);//画直线从0开始画到max_y
    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;
}
}

在主函数main中:

qmlRegisterType<OrdinateItem>("OrdinateItem.com", 1, 0, "OrdinateItem");//注册到qml中

在qml中引用:

import OrdinateItem.com 1.0

 

然后可以用了;

    OrdinateItem{ id: ordId; width: 20; height: parent.height*0.4; rulerTotal: 35; anchors.bottom: horId.top;
        //scaleViewPostion: 1
        MouseArea{ anchors.fill: parent;
            property point clickPos: "0,0"
            onPressed: {
                clickPos = Qt.point(mouse.x,mouse.y);
            }
            onPositionChanged: {
                //鼠标偏移量
                var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
                coordId.x = coordId.x+delta.x;
                coordId.y = coordId.y+delta.y;
            }
        }
    }


 



 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vqt5_qt6

你的鼓励是我们创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值