QT QWidget - 跑马灯

简介

关于前面画了个圆,怎么样也得跑个灯, 只是基于布局创建LED Widget而非 QTableView/QTableWidget;

实现步骤

  1. 实现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 


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

  1. 实现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;
};
  1. 功能代码
    MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#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);
}

演示

上图吧, 视频还要审核
QT QWidget - 跑马灯_第1张图片

代码

代码基本都在上面, 不需要特地下载
完整代码

你可能感兴趣的:(Qt,小技巧,qt)