Qt之实现移动的方块(蚂蚁线)

一、简介

移动的小方块或者说是类似移动的蚂蚁线,从一篇文章看到的,挺有趣的就自己做了一个,可以自由添加方块的个数,起始位置,方块的宽度,方块移动速度等待参数,下方是实现的代码,如果有需要新增的参数可以自行添加。

效果图

在这里插入图片描述

二、代码之路

AntsLineWidget.h

#pragma once

#include <QtWidgets/QWidget>
#include <QTimer>

class AntsLineWidget : public QWidget
{
    Q_OBJECT

public:
    AntsLineWidget(QWidget *parent = Q_NULLPTR);

    // 设置方块的宽度;
    void setBlockWidth(int width);

    // 根据起始位置生成方块;
    void generateBlockPath(int startPos);

    // 设置绿色位置;
    void setGreenPos(int greenPos);

    // 设置移动速度;
    void setMoveSpeed(int moveSeed);

private slots:
    // 更新位置;
    void updatePos();

private:
    void paintEvent(QPaintEvent *event);

    void resizeEvent(QResizeEvent *event);

private:
    // 方块移动时钟;
    QTimer m_moveTimer;
    // 方块绘制Path;
    QList<QPainterPath> m_blockPathList;
    // 方块宽度;
    int m_blockWidth;
    // 方块变绿位置;
    int m_greenPos;
    // 方块移动速度;
    int m_moveSpeed;
};


AntsLineWidget.cpp

#include "AntsLineWidget.h"
#include <QPainter>

#define SPACE_WIDTH 20

AntsLineWidget::AntsLineWidget(QWidget *parent)
    : QWidget(parent)
    , m_blockWidth(80)
    , m_greenPos(200)
    , m_moveSpeed(50)
{
    connect(&m_moveTimer, SIGNAL(timeout()), this, SLOT(updatePos()));
    m_moveTimer.start(m_moveSpeed);
}

void AntsLineWidget::setBlockWidth(int width)
{
    m_blockWidth = width;
}

void AntsLineWidget::generateBlockPath(int startPos)
{
    QPainterPath path;
    path.addRect(QRect(startPos, 2, m_blockWidth, this->height() - 3));
    m_blockPathList.append(path);
}

void AntsLineWidget::setGreenPos(int greenPos)
{
    m_greenPos = greenPos;
}

void AntsLineWidget::setMoveSpeed(int moveSpeed)
{
    m_moveSpeed = moveSpeed;
    m_moveTimer.setInterval(m_moveSpeed);
}

void AntsLineWidget::updatePos()
{
    for (int i = 0; i < m_blockPathList.count(); i++)
    {
        QPainterPath& path = m_blockPathList[i];
        // 移动步长;
        path.translate(QPoint(-2, 0));
        if (path.boundingRect().right() < SPACE_WIDTH)
        {
            QPainterPath pathNew;
            pathNew.addRect(QRect(this->width() - SPACE_WIDTH - m_blockWidth, 2, m_blockWidth, this->height() - 3));
            path = pathNew;
        }
    }

    update();
}

void AntsLineWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setPen(QPen(QColor(57, 141, 255), 3));

    painter.drawLine(QPoint(0, 0), QPoint(this->width(), 0));

    for (int i = 0; i < m_blockPathList.count(); i++)
    {
        QPainterPath path = m_blockPathList[i];
        if (path.boundingRect().left() < SPACE_WIDTH)
        {
            int headPathWidth = m_blockWidth - SPACE_WIDTH + path.boundingRect().left();
            int tailPathWidth = m_blockWidth - headPathWidth;
            QPainterPath newPath;
            newPath.addRect(QRect(SPACE_WIDTH, 2, headPathWidth, this->height() - 3));
            newPath.addRect(QRect(this->width() - SPACE_WIDTH - tailPathWidth, 2, tailPathWidth, this->height() - 3));
            if (newPath.contains(QPoint(m_greenPos, this->height() / 2)))
            {
                painter.fillPath(newPath, Qt::green);
            }
            else
            {
                painter.fillPath(newPath, Qt::gray);
            }
        }
        else
        {
            if (path.contains(QPoint(m_greenPos, this->height() / 2)))
            {
                painter.fillPath(path, Qt::green);
            }
            else
            {
                painter.fillPath(path, Qt::gray);
            }
        }
    }

    painter.setPen(QPen(Qt::red, 2));
    painter.drawLine(QPoint(m_greenPos, this->height() - 1), QPoint(m_greenPos, this->height() - 20));
    painter.setPen(QPen(QColor(57, 141, 255), 1));
    painter.drawLine(QPoint(SPACE_WIDTH, this->height() - 1), QPoint(this->width() - SPACE_WIDTH, this->height() - 1));
}

void AntsLineWidget::resizeEvent(QResizeEvent *event)
{
    for (int i = 0; i < m_blockPathList.count(); i++)
    {
        QPainterPath& path = m_blockPathList[i];
        QPainterPath pathNew;
        QRectF rect = path.boundingRect();
        rect.setHeight(this->height() - 3);
        pathNew.addRect(rect);
        path = pathNew;
    }
}

main.cpp

include "AntsLineWidget.h"
#include <QtWidgets/QApplication>
#include <QHBoxLayout>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    // 测试代码;
    QWidget * widget = new QWidget;
    QHBoxLayout* hLayout = new QHBoxLayout(widget);
    widget->resize(1000, 150);
    AntsLineWidget w(widget);
    w.generateBlockPath(20);
    w.generateBlockPath(160);
    w.generateBlockPath(300);
    hLayout->addWidget(&w);

    widget->show();
    return a.exec();
}


以前就是全部的实现代码和测试代码,整个工程代码大家也可以加群311750285进行下载,更多好玩,有趣的在等着你 ^ _ ^

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值