Qt自定义控件18(qml使用)

最近多在写qt界面,qwidget和qml界面都有在写,由于qml的画图没太多了解,只能先用qquickpainteditem画控件然后放在qml中使用,以又到liudianwu刘大神的控件设计中找了几个,自己实现了发出来,同时添加了动画效果,同时也是为了自己以后方便查看。希望有所帮助。由于这些控件暂时不用,所以我也就没做宽高自适应,望理解。源代码下载地址:https://download.youkuaiyun.com/download/parkchorong/13992830

老规矩,先上图
在这里插入图片描述

代码:
这里只展示一个,毕竟一法通,万法通。

#include "carpan.h"

#include <QPainter>
#include <QtMath>
#include <QPropertyAnimation>

#include <QDebug>

CarPan::CarPan(QQuickItem *parent) : QQuickPaintedItem(parent)
{
    initAnimation();
    setWidth(450);
    setHeight(450);

    this->r = (this->width() > this->height() ? this->height()/2 : this->width()/2);
    this->outoEL = this->r;
    resetValue();
}

void CarPan::setPointMode(int mode)
{
    qDebug() << __FUNCTION__ ;
    curPointMode = mode;
    update();
}

void CarPan::setValue(double value)
{
    qDebug() << __FUNCTION__ << value;
    this->lastValue = this->value;
    this->value = value;
//    update();
    qDebug() << __FUNCTION__ <<lastValue << " " <<value;
    initAnimation();
}

void CarPan::setR(double r)
{
    this->r = r;
    resetValue();
    update();

}

double CarPan::getR()
{
    this->r = (this->width() > this->height() ? this->height()/2 : this->width()/2);
    return this->r;
}

double CarPan::getValue()
{
    return this->value;
}

void CarPan::valueChanged(QVariant v)
{
    this->value = v.toInt();
    update();
}

void CarPan::paint(QPainter *painter)
{
    painter->setRenderHint(QPainter::Antialiasing);
    painter->translate(this->boundingRect().width()/2, this->boundingRect().height()/2);
    initOutE(painter);
    initInArc(painter);
    initInE(painter);
    initPointer(painter);
    initTextE(painter);
    initShortLine(painter);
    initLongLine(painter);
    initValueScale(painter);
    initOver(painter);
}

void CarPan::initOutE(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(QColor(80,80,80)));
    painter->drawEllipse(QRect(QPoint(-outoEL, -outoEL), QPoint(outoEL, outoEL)));
    painter->restore();

    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(QColor(60,60,60)));
    painter->drawEllipse(QRect(QPoint(-outIEL, -outIEL), QPoint(outIEL, outIEL)));
    painter->restore();
}

void CarPan::initInArc(QPainter *painter)
{
    painter->save();

    QPainterPath pathA;
    QPainterPath subPathA;
    QPainterPath pathB;
    QPainterPath subPathB;
    QPainterPath pathC;
    QPainterPath subPathC;

    pathA.arcTo(-inArcOL, -inArcOL, inArcOL*2, inArcOL*2, -45, 45);
    subPathA.arcTo(-inArcIL, -inArcIL, inArcIL*2, inArcIL*2, -45, 45);
    pathA -= subPathA;

    painter->setBrush(QColor(255, 107, 107));
    painter->setPen(Qt::NoPen);
    painter->drawPath(pathA);


    pathB.arcTo(-inArcOL, -inArcOL, inArcOL*2, inArcOL*2, 0, 45);
    subPathB.arcTo(-inArcIL, -inArcIL, inArcIL*2, inArcIL*2, 0, 45);
    pathB -= subPathB;

    painter->setBrush(QColor(218, 218, 0));
    painter->setPen(Qt::NoPen);
    painter->drawPath(pathB);

    pathC.arcTo(-inArcOL, -inArcOL, inArcOL*2, inArcOL*2, 45, 180);
    subPathC.arcTo(-inArcIL, -inArcIL, inArcIL*2, inArcIL*2, 45, 180);
    pathC -= subPathC;

    painter->setBrush(QColor(24, 189, 155));
    painter->setPen(Qt::NoPen);
    painter->drawPath(pathC);

    painter->restore();
}

void CarPan::initInE(QPainter *painter)
{
    painter->save();

    painter->setBrush(QColor(100, 100, 100));
    painter->setPen(Qt::NoPen);
    painter->drawEllipse(QRect(QPoint(-inArcIL, -inArcIL), QPoint(inArcIL, inArcIL)));

    painter->restore();
}

void CarPan::initTextE(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(QColor(223,105,105)));
    painter->drawEllipse(QRect(QPoint(-inTextEOL, -inTextEOL), QPoint(inTextEOL, inTextEOL)));
    painter->restore();

    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QBrush(QColor(250,250,250)));
    painter->drawEllipse(QRect(QPoint(-inTextEIL, -inTextEIL), QPoint(inTextEIL, inTextEIL)));
    painter->restore();

    painter->save();
    painter->setPen(Qt::black);
    QFont font = painter->font();
    font.setPointSize(18);
    font.setBold(true);
    painter->setFont(font);

    painter->drawText(QRect(QPoint(-inTextEIL, -inTextEIL), QPoint(inTextEIL, inTextEIL)), Qt::AlignCenter, QString::number(value));
    painter->restore();
}

void CarPan::initShortLine(QPainter *painter)
{
    double rotateCount = 270.0 / 100.0;
    painter->save();

    painter->setPen(Qt::white);
    painter->rotate(45);
    QLine line(QPoint(shortLineStart,0), QPoint(shortLineStop, 0));
    painter->drawLine(line);
    for (int i = 0; i < 100 ;i ++) {
        painter->rotate(-rotateCount);
        painter->drawLine(line);
    }

    painter->restore();
}

void CarPan::initLongLine(QPainter *painter)
{
    double rotateCount = 270.0 / 10.0;
    painter->save();

    painter->setPen(Qt::white);
    QPen pen = painter->pen();
    pen.setWidth(2);
    painter->setPen(pen);

    painter->rotate(45);
    QLine line(QPoint(longLineStart,0), QPoint(longtLineStop, 0));
    painter->drawLine(line);
    for (int i = 0; i < 10 ;i ++) {
        painter->rotate(-rotateCount);
        painter->drawLine(line);
    }

    painter->restore();
}

void CarPan::initValueScale(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::white);

    QFont font = painter->font();
    font.setPointSize(14);
    font.setBold(true);
    painter->setFont(font);

    double r = 45;
    float x = 0;
    float y = 0;

    for (int i = 0; i <= 100; i += 10) {
        x = longtLineStop * cos(r*M_PI/180);
        y = longtLineStop * sin(r*M_PI/180);

        switch (i) {
            case 0 : painter->drawText(QRect(x, y, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 10 : painter->drawText(QRect(x-5, y-3, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 20 : painter->drawText(QRect(x, y-15, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 30 : painter->drawText(QRect(x, y-24, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 40 : painter->drawText(QRect(x-5, y-30, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 50 : painter->drawText(QRect(x-22, y-31, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 60 : painter->drawText(QRect(x-32, y-23, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 70 : painter->drawText(QRect(x-35, y-20, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 80 : painter->drawText(QRect(x-40, y-15, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 90 : painter->drawText(QRect(x-38, y-10, 40,25), Qt::AlignCenter, QString::number((100 - i))); break;
            case 100 : painter->drawText(QRect(x-35, y, 40, 25), Qt::AlignCenter, QString::number((100 - i))); break;
        }

        r -= 27;
    }

    painter->restore();
}

void CarPan::initPointer(QPainter *painter)
{
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(QColor(223,105,105));
    painter->rotate(135 + value*(270.0/100.0));
    if (curPointMode == PanPointerMode::POINTMODE) {
        QPointF points[3] = {
            QPointF(0,12),QPointF(0,-12),QPointF(shortLineStop+5,0)
        };
        painter->drawPolygon(points,3);
    } else if (curPointMode == PanPointerMode::EMODE) {
        painter->drawEllipse(QRectF(inArcIL-30,-10,20,20));
    } else if (curPointMode == PanPointerMode::THREERECTMODE) {
        QPointF points[3] = {
            QPointF(inArcIL-23,12),QPointF(inArcIL-23,-12),QPointF(inArcIL-7,0)
        };
        painter->drawPolygon(points,3);
    } else if (curPointMode == PanPointerMode::POINTE) {
        painter->drawRoundedRect(QRect(inArcOL-5,-5,longtLineStop-inArcOL+3,10),4,4);

        QPointF points[4] = {
            QPointF(0,12),QPointF(0,-12),QPointF(longtLineStop,-2),QPointF(longtLineStop,2)
        };
        painter->drawPolygon(points,4);
    }
    painter->restore();
}

void CarPan::initOver(QPainter *painter)
{
    int radius = outIEL;
    painter->save();
    painter->setPen(Qt::NoPen);

    QPainterPath smallCircle;
    QPainterPath bigCircle;
    QPainterPath userfulArea;

    radius -= 1;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius *= 2;
    bigCircle.addEllipse(-radius, -radius + outoEL + outoEL/2, radius * 2, radius * 2);

    userfulArea = smallCircle - bigCircle;

    QLinearGradient linearGradient(0, -radius / 2, 0, 0);
    overColor.setAlpha(100);
    linearGradient.setColorAt(0.0, overColor);
    overColor.setAlpha(30);
    linearGradient.setColorAt(1.0, overColor);
    painter->setBrush(linearGradient);

    painter->rotate(-20);

    painter->drawPath(userfulArea);
    painter->restore();
}

void CarPan::initAnimation()
{   
    m_animation = new QPropertyAnimation(this);
    m_animation->setTargetObject(this);
    //根据曲线决定变化速度
    //    if (this->value > this->lastValue) {
    //        m_animation->setEasingCurve(QEasingCurve::InQuad);
    //    } else {
    //        m_animation->setEasingCurve(QEasingCurve::OutQuad);
    //    }

    m_animation->setDuration(500);
    m_animation->setStartValue(lastValue);
    m_animation->setEndValue(this->value);

    connect(m_animation,&QPropertyAnimation::valueChanged,this,&CarPan::valueChanged);

    m_animation->start();
}

void CarPan::resetValue()
{
    this->outoEL = this->r;
    this->outIEL = outoEL - 15;

    this->inArcOL = outoEL - 90;
    this->inArcIL = inArcOL - 25;

    this->inTextEOL = inArcOL - 60;
    this->inTextEIL = inTextEOL - 5;

    this->shortLineStart = inArcOL + 20;
    this->shortLineStop = inArcOL + 34;

    this->longLineStart = inArcOL + 16;
    this->longtLineStop = inArcOL + 34;

    qDebug() << __FUNCTION__ <<outoEL;
}

qml加载代码

#include <QGuiApplication>
#include <QQmlApplicationEngine>

#include "carpan.h"
#include "arcpan.h"
#include "perpan.h"
#include "halfepan.h"
#include "progpan.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
//    qApp->setAttribute(Qt::AA_UseOpenGLES);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;

    qmlRegisterType<CarPan>("CarPan", 1, 0, "CarPan");
    qmlRegisterType<ArcPan>("ArcPan", 1, 0, "ArcPan");
    qmlRegisterType<PerPan>("PerPan", 1, 0, "PerPan");
    qmlRegisterType<HalfEPan>("HalfEPan", 1, 0, "HalfEPan");
    qmlRegisterType<ProGPan>("ProGPan",1,0,"ProGPan");

    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    return app.exec();
}

qml代码

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Layouts 1.12
import QtQuick.Controls 1.4
import CarPan 1.0
import ArcPan 1.0
import PerPan 1.0
import HalfEPan 1.0
import ProGPan 1.0

Window {
    visible: true
    width: 1000
    height: 750
    title: qsTr("Hello World")
    CarPan{
        id:carPan1
        width: 450
        height: 450
        x:0
        y: 0
        Component.onCompleted: {
            setR(220);
        }

    }

    ArcPan{
        id:arcPan
        width: 450
        height: 450
        x:500
        y: 500
    }

    HalfEPan{
        id:halfEPan
        width: 450
        height: 450
        x:0
        y: 500
    }

    PerPan{
        id: perPan
        width: 500
        height: 500
        x: 500
        y: 0
        Component.onCompleted: {
            perPan.setR(235);
        }
    }

    ProGPan{
        id: proGPan
        width: 500
        height: 500
        x: 1000
        y: 0
        Component.onCompleted: {
        }
    }

    ComboBox{
        model: ListModel {
            ListElement { key: "PointMde"; text: "PointMde"; value: 0 }
            ListElement { key: "Emode"; text: "Emode"; value: 1 }
            ListElement { key: "ThreeAcMode"; text: "ThreeAcMode"; value: 2 }
            ListElement { key: "PointEMode"; text: "PointEMode"; value: 3 }
        }
        onCurrentIndexChanged: {
            carPan1.setPointMode(currentIndex);
            halfEPan.setMode(currentIndex);
            proGPan.setMode(currentIndex);
        }
    }
    Slider{
       minimumValue: 0;
       maximumValue: 100
       stepSize: 1.0
       width: 300
       height: 30
       anchors.top: carPan1.bottom
       anchors.topMargin: 20
       onValueChanged: {
           carPan1.setValue(value);
           arcPan.setValue(value);
           perPan.setValue(value);
           halfEPan.setValue(value);
           console.log(value);
       }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

制造垃圾代码的垃圾coder一个

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

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

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

打赏作者

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

抵扣说明:

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

余额充值