• 63阅读
  • 0回复

qt lcd 显示控件 [复制链接]

上一主题 下一主题
离线黏过往的
 

只看楼主 倒序阅读 楼主  发表于: 04-28
效果如下:



#ifndef QTLCDLABEL_H
#define QTLCDLABEL_H

#include <QLabel>
#include <QPainter>
#include <QPaintEvent>
#include <QImage>
#include <QTimer>

class QtLCDLabel : public QLabel
{
    Q_OBJECT
public:
    QtLCDLabel(QWidget *parent = nullptr);
    ~QtLCDLabel();

    void setText(QString text);
    void setPixelSize(int size)   { m_pixelSize = size; this->update();}
    void setSpacingSize(int size) { m_spacingSize = size; this->update();}
    void setTextColor(QColor color) { m_textColor = color; this->update();}
    void setPixelColor(QColor color) { m_pixelColor = color; this->update();}
    void setBackgroundColor(QColor color) { m_backgroundColor = color; this->update();}
    void setAutoScroll(bool flags);

protected:
    void paintEvent(QPaintEvent *pEvent);
    void resizeEvent(QResizeEvent *pEvent);
    QImage generateDotMatrix(const QString &text);
    QImage generateBackgroundDotMatrixImage();
    QImage generateDotMatrixImage(const QImage& source);

private:
    int m_scrollOffset = 0;
    QTimer *m_timer = nullptr;
    QImage m_textImage;
    QImage m_textDotMatrixImage;       // 绿色文字点阵图(提前生成好)
    QImage m_backgroundDotMatrixImage; // 灰色背景点阵图(只在resize时候生成一次)

    int m_pixelSize   = 2;
    int m_spacingSize = 1;

    QColor m_textColor = Qt::red;
    QColor m_pixelColor = QColor::fromRgb(32, 32, 32);
    QColor m_backgroundColor = Qt::black;

    bool m_IsAutoScroll = false;
};

#endif // QTLCDLABEL_H


#include "qtlcdlabel.h"
#include <QDebug>

QtLCDLabel::QtLCDLabel(QWidget *parent)
          : QLabel(parent)
{

}

void QtLCDLabel::setAutoScroll(bool flags){
    if(flags){
        if(nullptr == m_timer){
            m_timer = new QTimer(this);
            connect(m_timer, &QTimer::timeout, this, [this]() {
                m_scrollOffset += 4;
                // 重绘
                update();
            });
        }
        m_timer->start(50);
    }else{
        if(nullptr != m_timer){
            m_timer->stop();
        }
    }
}

QtLCDLabel::~QtLCDLabel(){

}

void QtLCDLabel::setText(QString text){
    m_textImage = generateDotMatrix(text);
    // 清空点阵图,表示需要重新生成
    m_textDotMatrixImage = QImage();
    update();
}
void QtLCDLabel::resizeEvent(QResizeEvent *pEvent){
    m_backgroundDotMatrixImage = generateBackgroundDotMatrixImage();
    QLabel::resizeEvent(pEvent);
}

QImage QtLCDLabel::generateBackgroundDotMatrixImage()
{
    QImage image(width(), height(), QImage::Format_ARGB32);
    image.fill(m_backgroundColor);

    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing);

    for (int y = 0; y < height(); y += (m_pixelSize + m_spacingSize))
    {
        for (int x = 0; x < width(); x += (m_pixelSize + m_spacingSize))
        {
            QRect rect(x, y, m_pixelSize, m_pixelSize);
            painter.fillRect(rect, m_pixelColor);
        }
    }

    return image;
}

QImage QtLCDLabel::generateDotMatrix(const QString &text){

    // 1. 基础设置
    QFont font;
    font.setFamily("宋体");
    font.setBold(true);
    // font.setItalic(true);

    // 2. 先粗略估计字体大小,让它能填满控件宽度一定比例
    // 让字体高度大概是控件高度的60%
    // 字号和像素高度大致比例调整一下
    int targetHeight = height() * 0.2;
    int pointSize    = targetHeight / 2.0;
    font.setPointSize(pointSize);

    QFontMetrics fm(font);
    int textWidth = fm.horizontalAdvance(text);
    int textHeight = fm.height();

    if(textWidth <= 0 || textHeight <= 0)
    {
        return QImage();
    }

    // 4. 创建适配的图片
    QImage image(textWidth, textHeight, QImage::Format_ARGB32);
    image.fill(Qt::transparent);

    // 5. 绘制
    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setFont(font);
    painter.setPen(Qt::white);
    painter.drawText(image.rect(), Qt::AlignLeft | Qt::AlignVCenter, text);
    painter.end();

    return image;
}

QImage QtLCDLabel::generateDotMatrixImage(const QImage& source)
{
    int matrixWidth = source.width() * (m_pixelSize + m_spacingSize) - m_spacingSize;
    int matrixHeight = source.height() * (m_pixelSize + m_spacingSize) - m_spacingSize;

    QImage image(matrixWidth, matrixHeight, QImage::Format_ARGB32);
    image.fill(Qt::transparent);

    QPainter painter(&image);
    painter.setRenderHint(QPainter::Antialiasing);

    for (int y = 0; y < source.height(); ++y)
    {
        for (int x = 0; x < source.width(); ++x)
        {
            QColor pixelColor = source.pixelColor(x, y);
            if (pixelColor.alpha() > 128)
            {
                int rectX = x * (m_pixelSize + m_spacingSize);
                int rectY = y * (m_pixelSize + m_spacingSize);
                QRect rect(rectX, rectY, m_pixelSize, m_pixelSize);
                painter.fillRect(rect, m_textColor);
            }
        }
    }

    return image;
}

void QtLCDLabel::paintEvent(QPaintEvent *pEvent){
    QLabel::paintEvent(pEvent);
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    if (!m_backgroundDotMatrixImage.isNull())
        painter.drawImage(0, 0, m_backgroundDotMatrixImage);

    if (m_textImage.isNull())
        return;

    if (m_textDotMatrixImage.isNull())
    {
        m_textDotMatrixImage = generateDotMatrixImage(m_textImage);
    }

    if (!m_textDotMatrixImage.isNull())
    {
        int startX = (width() - m_textDotMatrixImage.width()) / 2;
        int matrixWidth = m_textDotMatrixImage.width();

        if (m_IsAutoScroll && matrixWidth > width())
        {
            startX = -m_scrollOffset;
            if (m_scrollOffset > matrixWidth)
                m_scrollOffset = 0;
        }

        int offsetY = (height() - m_textDotMatrixImage.height()) / 2;
        painter.drawImage(startX, offsetY, m_textDotMatrixImage);
    }
}
码云地址:https://gitee.com/miaoxingxing/qt-lcd---display-control.git

快速回复
限100 字节
 
上一个 下一个