效果如下:
#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