简介
关于前面画了个圆,怎么样也得跑个灯, 只是基于布局创建LED Widget而非 QTableView/QTableWidget;
实现步骤
- 实现LED Widget
LEDWidget.cpp
LEDWidget::LEDWidget(QWidget *parent)
: QWidget(parent), m_on(false)
{
}
void LEDWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QPen pen;
pen.setColor(QColor(128, 128, 128)); // 设置线颜色为浅灰色
painter.setPen(pen);
// 设置LED灯的颜色和大小
// QColor ledColor(85, 239, 196); // 红色
int ledSize = std::max(20, width() >= height() ? height() - 10 : width() - 10);
QLinearGradient gradient(0, 0, width(), height());
if (m_on)
{
gradient.setColorAt(0, "#43e97b");
gradient.setColorAt(1, "#38f9d7");
}
else
{
gradient.setColorAt(0, "#e6e9f0");
gradient.setColorAt(1, "#eef1f5");
}
painter.setBrush(gradient);
// 计算LED灯的位置
int x = (width() - ledSize) / 2;
int y = (height() - ledSize) / 2;
// 绘制LED灯的主体
// painter.setBrush(ledColor);
painter.drawEllipse(x, y, ledSize, ledSize);
}
LEDWidget.h
#ifndef LEDWIDGET_H
#define LEDWIDGET_H
#include <QWidget>
class LEDWidget : public QWidget
{
public:
LEDWidget(QWidget *parent = nullptr);
inline void controlLed(bool on=false)
{
if (on != m_on)
{
m_on = on;
update();
}
}
inline void toggleLed()
{
m_on = !m_on;
update();
}
protected:
void paintEvent(QPaintEvent *event) override;
bool m_on;
};
#endif // LEDWIDGET_H
- 实现MarqueeLED
只需要改变数字绑定信号,自动亮灭灯
/**
* @brief The MarqueeLED class
* @ note 跑马灯类, 亮灯号一致则点亮,不一致则熄灭
*/
class MarqueeLED : public LEDWidget
{
public:
MarqueeLED(QWidget *parent=nullptr) :
LEDWidget(parent), m_num(-1)
{
}
void setNum(int num) { m_num = num; }
public slots:
void onLightUpNumberChanged(int num)
{
controlLed(num == m_num);
}
private:
int m_num;
};
- 功能代码
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGridLayout>
#include "ledwidget.h"
/**
* @brief The MarqueeLED class
* @ note 跑马灯类, 亮灯号一致则点亮,不一致则熄灭
*/
class MarqueeLED : public LEDWidget
{
public:
MarqueeLED(QWidget *parent=nullptr) :
LEDWidget(parent), m_num(-1)
{
}
void setNum(int num) { m_num = num; }
public slots:
void onLightUpNumberChanged(int num)
{
controlLed(num == m_num);
}
private:
int m_num;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow), m_currIndex(0)
{
ui->setupUi(this);
uiInit();
}
MainWindow::~MainWindow()
{
widgetFree();
delete ui;
}
void MainWindow::uiInit()
{
ui->btnStop->setEnabled(false);
QGridLayout *ly = new QGridLayout(ui->wgtLeds);
ui->wgtLeds->setLayout(ly);
connect(ui->btnStart, &QPushButton::clicked, this, &MainWindow::onStart);
connect(ui->btnStop, &QPushButton::clicked, this, &MainWindow::onStop);
connect(&m_actTimer, &QTimer::timeout, this, &MainWindow::onActionTimerTimeout);
}
void MainWindow::widgetFree()
{
QGridLayout *ly = qobject_cast<QGridLayout*> (ui->wgtLeds->layout());
for (QWidget *wgt : m_ledWidgets)
{
ly->removeWidget(wgt);
delete wgt;
wgt = nullptr;
}
m_ledWidgets.clear();
}
void MainWindow::onActionTimerTimeout()
{
int lightUpNum = m_currIndex;
emit numberChanged(lightUpNum);
++m_currIndex;
if ( m_currIndex >= (ui->sbColumns->value() * ui->sbRows->value()) )
m_currIndex = 0;
}
void MainWindow::onStart()
{
ui->btnStop->setEnabled(false);
ui->btnStart->setEnabled(false);
QGridLayout *ly = qobject_cast<QGridLayout*> (ui->wgtLeds->layout());
for (int rowIndex = 0; rowIndex < ui->sbRows->value(); ++rowIndex)
{
for (int colIndex = 0; colIndex < ui->sbColumns->value(); ++colIndex)
{
MarqueeLED *wgt = new MarqueeLED(this);
wgt->setNum(rowIndex * ui->sbColumns->value() + colIndex); // 0 ~ x
m_ledWidgets.append(wgt);
ly->addWidget(wgt, rowIndex, colIndex);
connect(this, &MainWindow::numberChanged, wgt, &MarqueeLED::onLightUpNumberChanged);
}
}
m_actTimer.setTimerType(Qt::PreciseTimer);
m_actTimer.setInterval(ui->sbIntervalTime->value());
m_actTimer.start();
ui->btnStop->setEnabled(true);
ui->btnStart->setEnabled(false);
}
void MainWindow::onStop()
{
m_actTimer.stop();
widgetFree();
m_currIndex = 0;
ui->btnStop->setEnabled(false);
ui->btnStart->setEnabled(true);
}
演示
上图吧, 视频还要审核
代码
代码基本都在上面, 不需要特地下载
完整代码