QT自定义控件之车辆喇叭

基于QT 设计实现的车辆喇叭控件.

1.设计说明

基于QWidget设计实现,通过重构QPaintEvent事件,绘制出的车辆远近光灯控件,可通过QWidget提升方法,应用于项目中.
特征如下:

  • 支持车辆喇叭开/关状态显示
  • 支持车辆喇叭朝左/右设置
  • 支持喇叭背景颜色设置

2.核心代码

#ifndef QCUSTOMHORN_H
#define QCUSTOMHORN_H

#include <QWidget>
#include <QPainter>

/**
 * @brief Feature:
 * Support Horn Active/DisActive
 * Support Horn Direction
 * Support
 * Support
 */

#ifdef quc
#if (QT_VERSION < QT_VERSION_CHECK(5,0,0))
#include <QtDesigner/QDesignerExportWidget>
#else
#include <QtUiPlugin/QDesignerExportWidget>
#endif

class QDESIGNER_WIDGET_EXPORT QCustomMobileSignal : public QWidget
#else
class QCustomHorn : public QWidget
#endif
{
    Q_OBJECT
public:
    enum HornDir
    {
        HORNDIR_LEFT  = 0,
        HORNDIR_RIGHT = 1,
    };

    explicit QCustomHorn(QWidget *parent = nullptr);
    ~QCustomHorn();

protected:
    QSize sizeHint()                const;
    QSize minimumSizeHint()         const;

    void paintEvent(QPaintEvent *);
    void resizeEvent(QResizeEvent *);

    void drawBackground(QPainter *painter);
    void drawHorn(QPainter *painter);
    void drawVehicleHorn(QPainter *painter);
private:
    QColor m_active_color_;
    QColor m_unactive_color_;
    // false:unactive true:active
    bool m_horn_active_{false};
    HornDir m_dir_{HORNDIR_LEFT};
    QColor m_background_color_;

signals:

public slots:
    void setHornState(const bool value);
    void setHornDir(const HornDir value);
};

#endif // QCUSTOMHORN_H


#include "qcustomhorn.h"

QCustomHorn::QCustomHorn(QWidget *parent) : QWidget(parent)
{
    m_background_color_ = QColor(55,107,154, 30);

    m_active_color_ = Qt::yellow;
    m_unactive_color_ = Qt::gray;
}


QCustomHorn::~QCustomHorn()
{

}


void QCustomHorn::resizeEvent(QResizeEvent *)
{
    this->repaint();
}


QSize QCustomHorn::sizeHint() const
{
    return QSize(150, 150);
}

QSize QCustomHorn::minimumSizeHint() const
{
    return QSize(30, 30);
}

void QCustomHorn::paintEvent(QPaintEvent *)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    //绘制准备工作,启用反锯齿,平移坐标轴中心,等比例缩放
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
    painter.translate(width / 2, height / 2);
    painter.scale(side / 200.0, side / 200.0);

    drawBackground(&painter);

//    drawHorn(&painter);
    drawVehicleHorn(&painter);

//    drawTitle(&painter);

//    drawTimeCost(&painter);

//    drawSystemTime(&painter);
}

void QCustomHorn::drawBackground(QPainter *painter)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    painter->save();

    painter->setBrush(m_background_color_);
    painter->drawRect(-width, -height, width * 2, height * 2);

    painter->restore();
}

void QCustomHorn::drawHorn(QPainter *painter)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);

    painter->save();

    static const QPoint points[] = {
        QPoint(-10,  -5),
        QPoint( 48,  -5),
        QPoint( 58, -28),
        QPoint( 58,  28),
        QPoint( 48,   5),
        QPoint(-10,   5),
    };

    static const QLine lines[] = {
        {-10, -7, 58, -7},
        {-10,  7, 42,  7},
        { 113,-40, 113,  40},
    };
//    QRectF target(-40.0, -30.0, 80.0, 60.0);

//    if (m_horn_active_)
//    {
//        QImage image(":/resource/image/horn_on.png");
//        painter->setPen(QPen(m_active_color_, 4));
//        painter->drawImage(target, image);
//    } else {
//        QImage image(":/resource/image/horn_off.png");
//        painter->setPen(QPen(m_unactive_color_, 4));
//        painter->drawImage(target, image);
//    }
    if (m_horn_active_)
    {
        painter->setPen(QPen(Qt::green, 6));
    } else {
        painter->setPen(QPen(Qt::gray, 6));
    }


    painter->drawEllipse(-50, -20, 40, 40);

    QRectF rectangle2(2.0, -7.0, 60.0, 40.0);
    int startAngle2 = 90 * 16;
    int spanAngle2 = -280 * 16;
    painter->drawArc(rectangle2, startAngle2, spanAngle2);

    QRectF rectangle3(18.0, 3.0, 30.0, 20.0);
    int startAngle3 = 36 * 16;
    int spanAngle3 = -230 * 16;
    painter->drawArc(rectangle3, startAngle3, spanAngle3);

//    painter->drawPolygon(points, sizeof(points)/sizeof(points[0]));
    painter->drawLines(lines, sizeof(lines)/sizeof(lines[0]));

    QRectF rectangle(10.0, -87.0, 100.0, 80.0);
    int startAngle = 270 * 16;
    int spanAngle = 80 * 16;
    painter->drawArc(rectangle, startAngle, spanAngle);

    QRectF rectangle1(10.0, 7.0, 100.0, 80.0);
    int startAngle1 = 90 * 16;
    int spanAngle1 = -80 * 16;
    painter->drawArc(rectangle1, startAngle1, spanAngle1);

    painter->restore();
}

void QCustomHorn::drawVehicleHorn(QPainter *painter)
{
    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);
    QRectF target(-128.0, -83.0, 256.0, 165.0);

    painter->save();

    if (m_horn_active_)
    {
        QImage image(":/resource/image/horn_on.png");
        if (m_dir_ == HORNDIR_LEFT)
        {
            painter->drawImage(target, image.mirrored(true, false));
        } else {
            painter->drawImage(target, image);
        }

    } else {
        QImage image(":/resource/image/horn_off.png");
        if (m_dir_ == HORNDIR_LEFT)
        {
            painter->drawImage(target, image.mirrored(true, false));
        } else {
            painter->drawImage(target, image);
        }

    }


    painter->restore();
}

void QCustomHorn::setHornState(const bool value)
{
    if (this->m_horn_active_ != value)
    {
        this->m_horn_active_ = value;
        this->update();
    }
}

void QCustomHorn::setHornDir(const HornDir value)
{
    if (this->m_dir_ != value)
    {
        this->m_dir_ = value;
        this->update();
    }
}

3.效果示意图

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值