效果:
头文件
#ifndef HACKRAIN_H
#define HACKRAIN_H
#include <QWidget>
#include <QPlainTextEdit>
#include <QTimerEvent>
class HackRain : public QWidget
{
Q_OBJECT
public:
explicit HackRain(QWidget *parent = nullptr);
~HackRain();
struct RainText
{
RainText() {}
int startRow = 0;
int endRow = 0;
int col = 0;
int speed = 1; //下降的速度
QString text;
void init(){
endRow = startRow + text.length() - 1;
}
};
protected:
void initialize();
RainText getRainLine();
void getCanAddCol(RainText &rText);
void updateFrame();
void timerEvent(QTimerEvent *event);
private:
QPlainTextEdit *m_pPlaineText = nullptr;
QVector<RainText> m_vecAllRains;
int m_nTimerID = -1;
};
#endif // HACKRAIN_H
源文件
#include "hackrain.h"
#include <QVBoxLayout>
#include <QtMath>
HackRain::HackRain(QWidget *parent) : QWidget(parent)
{
initialize();
}
HackRain::~HackRain()
{
if(m_nTimerID != -1){
this->killTimer(m_nTimerID);
}
}
void HackRain::initialize()
{
QVBoxLayout *pLayout = new QVBoxLayout;
m_pPlaineText = new QPlainTextEdit;
pLayout->addWidget(m_pPlaineText);
m_pPlaineText->setStyleSheet("QPlainTextEdit{"
"background-color:black;"
"color:green;"
"}");
this->setLayout(pLayout);
this->resize(650,650);
m_pPlaineText->setEnabled(false);
for (int i = 0; i < 50; ++i) {
m_vecAllRains.append(getRainLine());
}
m_nTimerID = this->startTimer(1000/24);
}
HackRain::RainText HackRain::getRainLine()
{
QStringList riansTexts;
riansTexts << "Hello world" << "Yes My baby" << "void main()";
RainText rText;
rText.startRow = qrand() % 80;
rText.text = riansTexts.at(qrand() % 3);
rText.init();
getCanAddCol(rText);
return rText;
}
void HackRain::getCanAddCol(HackRain::RainText &rText)
{
rText.col = qrand() % 100;
rText.speed = qrand() % 5 + 1;
if(m_vecAllRains.count() == 0){
return;
}
bool canAdd = true;
for(HackRain::RainText t:m_vecAllRains){
if(t.col == rText.col &&
t.startRow <= rText.endRow){
canAdd = false;
break;
}
}
if(!canAdd){
getCanAddCol(rText);
}
}
void HackRain::updateFrame()
{
m_pPlaineText->clear();
QString texts;
if(m_vecAllRains.isEmpty()){
return;
}
for (int r = 0; r < 40; ++r) {
for (int c = 0; c < 100; ++c) {
bool isDot = true;
for(HackRain::RainText rText:m_vecAllRains){
if(rText.col == c &&
(rText.startRow <= r && rText.endRow >= r)){
texts.append(rText.text.at(r - rText.startRow));
isDot = false;
break;
}
}
if(isDot){
texts.append(".");
}
}
texts += "\n";
}
int i = 0;
for(HackRain::RainText rText:m_vecAllRains){
rText.startRow += rText.speed;
if(rText.startRow >= 100){
rText.startRow = 0;
rText.init();
getCanAddCol(rText);
}else{
rText.init();
}
m_vecAllRains[i] = rText;
++i;
}
m_pPlaineText->appendPlainText(texts);
}
void HackRain::timerEvent(QTimerEvent *event)
{
QWidget::timerEvent(event);
updateFrame();
}