1. #pragma once
    2. #include <QtWidgets/QWidget>
    3. #include "ui_hackRain.h"
    4. #include <QMouseEvent>
    5. #include <QVector>
    6. #define RainNum 200
    7. #define StrNum 10
    8. #define CharH 30
    9. struct Rain
    10. {
    11. int x; // 雨串开始点x
    12. int y; // 雨串开始点y
    13. QString str; // 代码雨的字串
    14. };
    15. class hackRain : public QWidget
    16. {
    17. Q_OBJECT
    18. public:
    19. hackRain(QWidget *parent = Q_NULLPTR);
    20. public:
    21. void initRain();
    22. // 给字体着色
    23. void render();
    24. // 更新位置
    25. void update();
    26. private:
    27. Ui::hackRainClass ui;
    28. QRect m_Screen;
    29. Rain m_rains[RainNum];
    30. QPainter* m_painter;
    31. private:
    32. void paintEvent(QPaintEvent* event);
    33. void mouseMoveEvent(QMouseEvent* event);
    34. };
    1. #include "hackRain.h"
    2. #include <QDesktopWidget>
    3. #include <QPainter>
    4. #include <QPen>
    5. #include <QBrush>
    6. #include <QDebug>
    7. #include <QRandomGenerator>
    8. #include <QTimer>
    9. #include <QIcon>
    10. int rnd(int beg, int end)
    11. { // 返回 [beg,end)内的一个int值
    12. return QRandomGenerator::global()->bounded(beg, end);
    13. }
    14. hackRain::hackRain(QWidget *parent)
    15. : QWidget(parent)
    16. {
    17. ui.setupUi(this);
    18. // 无边框窗口, 黑色背景
    19. this->setWindowFlags(Qt::FramelessWindowHint);
    20. this->setStyleSheet("background-color:black;");
    21. // 使画布全屏
    22. m_Screen = QDesktopWidget().screenGeometry(); // 获取桌面 QRect(0,0 2560x1440)
    23. this->resize(m_Screen.width(), m_Screen.height()); // 令窗口大小和桌面大小一样
    24. // 构建m_rains
    25. initRain();
    26. m_painter = new QPainter(this);
    27. m_painter->setFont(QFont("Times", CharH));
    28. QTimer* timer = new QTimer(this);
    29. timer->start(50); // 每隔50ms发送信号
    30. connect(timer, &QTimer::timeout, [=]() {
    31. QWidget::update(); // 重绘画面,调用paintEvent()
    32. });
    33. }
    34. void hackRain::initRain()
    35. {
    36. for (int i = 0; i < RainNum; i++) {
    37. m_rains[i].x = rnd(0, m_Screen.width());
    38. m_rains[i].y = rnd(0, m_Screen.height());
    39. for (int j = 0; j < StrNum; j++) {
    40. int type = rnd(0, 3); // 0数字,1小写字母,2大写字母
    41. char ch;
    42. if (type == 0)
    43. ch = rnd('0', '9' + 1);
    44. else if (type == 1)
    45. ch = rnd('a', 'z' + 1);
    46. else
    47. ch = rnd('A', 'Z' + 1);
    48. m_rains[i].str.append(ch);
    49. }
    50. }
    51. }
    52. void hackRain::paintEvent(QPaintEvent* event)
    53. {
    54. m_painter->begin(this);
    55. for (int i = 0; i < RainNum; i++) {
    56. m_rains[i].y += CharH * rnd(1, 3); // 降落1~2个字符
    57. // 若雨滴已经完全落下, 则让它从上面重新复活
    58. if (m_rains[i].y >= m_Screen.height() + StrNum * CharH) {
    59. m_rains[i].x = rnd(0, m_Screen.width());
    60. m_rains[i].y = 0;
    61. }
    62. for (int j = 0; j < StrNum; j++) {
    63. QPen penGreen(QColor(0, 255 - 20 * j, 0)); // 颜色渐浅
    64. m_painter->setPen(penGreen);
    65. Rain rain = m_rains[i];
    66. int x = m_rains[i].x;
    67. int y = m_rains[i].y - j * CharH;
    68. m_painter->drawText(x, y, m_rains[i].str.at(j));
    69. }
    70. }
    71. m_painter->end();
    72. }
    73. void hackRain::mouseMoveEvent(QMouseEvent* event)
    74. {
    75. qApp->quit(); // 移动后退出
    76. }