一、前言
刷博客时看到了背景的字母雨,想用qt也实现一下。通过自定义RainDrop类,调用该类在QPaintEvent绘图事件里实现对字母文本的绘制。
二、代码
RainDrop自定义字母雨类
class RainDrop
{
public:
RainDrop(int x, int y, int speed, int width, int height, int length)
: m_x(x), m_y(y), m_speed(speed), m_width(width),
m_height(height), m_length(length)
{
m_letters.resize(length);
for (int i = 0; i < length; ++i) {
m_letters[i] = QChar('A' + qrand() % 26);
}
}
void move()
{
m_y += m_speed;
if (m_y >= m_height) {
m_y = -m_length;
for (int i = 0; i < m_length; ++i) {
m_letters[i] = QChar('A' + qrand() % 26);
}
}
}
void draw(QPainter& painter)
{
painter.setPen(QColor(0,180,0));
for (int i = 0; i < m_length; ++i) {
if(i == m_length - 1)
painter.setPen(QColor(180,180,180));
else
painter.setPen(QColor(0, 100 + 10 * i, 0));
painter.drawText(m_x, m_y + i * m_width, QString(m_letters[i]));
}
}
private:
int m_x;
int m_y;
int m_speed;
int m_width;
int m_height;
int m_length;
QVector<QChar> m_letters;
};
Widget绘制界面
class Widget : public QWidget
{
public:
Widget(QWidget* parent = nullptr)
: QWidget(parent), m_timerId(0)
{
setWindowTitle("Letter Rain");
QPalette palette;
palette.setColor(QPalette::Background, Qt::black);
setPalette(palette);
setFixedSize(600, 400);
m_rainDrops.reserve(100);
for (int i = 0; i < 100; ++i) {
int x = qrand() % width();
int y = -(qrand() % height());
int speed = qrand() % 8 + 1;
int width = 10;
int height = this->height();
int length = qrand() % 10 + 5;
m_rainDrops.append(RainDrop(x, y, speed, width, height, length));
}
m_timerId = startTimer(50);
}
protected:
void paintEvent(QPaintEvent* event) override
{
QPainter painter(this);
for (auto rainDrop : m_rainDrops) {
rainDrop.draw(painter);
}
}
void timerEvent(QTimerEvent* event) override
{
for (auto& rainDrop : m_rainDrops) {
rainDrop.move();
}
update();
}
private:
QList<RainDrop> m_rainDrops;
int m_timerId;
};
main
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
Widget widget;
widget.show();
return app.exec();
}
三、效果