一个简单的打字软件

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/qq_32768743/article/details/89005967

软件需求

  • 打字练习的UI界面保持和windows版本一致
    在这里插入图片描述

  • 图标从简,只显示文字

    • 时间
    • 速度
    • 进度
    • 正确率
    • 重置
    • 暂停
  • 课程选择,使用下拉列表框

  • 去掉其他的部分

  • 打字的部分实现

    • 仅支持英文
    • 需要打的字为黑色,打字正确变成灰色,错误变成红色,都需要变
    • 自动换行
    • 每篇文章分成多个页,不同页之前不能干扰
    • 每页有5行输入的文本

当前实现的一个核心展示
在这里插入图片描述
后面继续完善。
代码很简单
头文件

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = 0);
    ~Widget();


    // QWidget interface
protected:
    void paintEvent(QPaintEvent *event) override;
    void keyReleaseEvent(QKeyEvent *event) override;

private:
    QRect genTargetTextRect(int i, int j);
    QRect genInputTextRect(int i, int j);
    QLineF genCursorLine(int i, int j);
    void drawWrongChar(QPainter &painter, int i, int j, QChar targetCh, QChar inputCh);
    void drawCorrectChar(QPainter &painter, int i, int j, QChar ch);
    void drawCursor(QPainter &painter);
    void nextPageJudge();
private:
    QString m_text;
    QString m_input;
    QStringList m_pageText;
    int m_eachLineCharCount;
    int m_fontWidth;
    int m_lineHeight;
    bool m_cursorShow;
    int m_pageNum;
    int m_eachPageLineCount;
};

#endif // WIDGET_H

cpp文件

#include "widget.h"
#include <QtCore>
#include <QtWidgets>
Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_eachLineCharCount = 50;
    m_fontWidth = 24;
    m_lineHeight = 30;
    m_cursorShow = true;
    m_pageNum = 0;
    m_eachPageLineCount = 5;
    resize(m_eachLineCharCount * m_fontWidth + 10, height());
    QFile file(":/test.txt");
    file.open(QIODevice::ReadOnly);
    auto text = file.readAll();
    for(int i = 0; i * m_eachPageLineCount * m_eachLineCharCount < text.length(); i++ ) {
        int index = i * m_eachPageLineCount * m_eachLineCharCount;
        int len = m_eachPageLineCount * m_eachLineCharCount;
        m_pageText.append(text.mid(index, len));
    }
    auto timer = new QTimer(this);
    connect(timer, &QTimer::timeout, [=]() {
       this->update();
    });
    timer->setInterval(500);
    timer->start();
    m_input = "Go0d ";
    m_text = m_pageText[m_pageNum];
}

Widget::~Widget()
{

}

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    QPainter painter(this);
    auto font = painter.font();
    font.setPixelSize(m_fontWidth);
    painter.setFont(font);
    for(int i = 0; i * m_eachLineCharCount < m_text.length(); i++) {
        for(int j = 0; j < m_eachLineCharCount; j++) {
            int index = i * m_eachLineCharCount + j;
            if (m_input.length() <= index) {
                auto textRect = genTargetTextRect(i, j);
                painter.drawText(textRect, Qt::AlignCenter, QString(m_text[index]));
            } else {
                if (m_text[index] == m_input[index]) {
                    drawCorrectChar(painter, i, j, m_text[index]);
                } else {
                    drawWrongChar(painter, i, j, m_text[index], m_input[index]);
                }
            }
        }
    }
    drawCursor(painter);
}

void Widget::keyReleaseEvent(QKeyEvent *event)
{
    switch (event->key()) {
    case Qt::Key_Backspace:
        m_input.remove(m_input.length() -1, 1);
        break;
    default:
        auto key = event->text();
        if (key.isEmpty()) {
            // ignore
        } else {
            m_input.append(key);
            nextPageJudge();
        }
        break;
    }
    update();
}

QRect Widget::genTargetTextRect(int i, int j)
{
    int y = i * m_lineHeight * 2;
    int x = j * m_fontWidth;
    return QRect(x, y, m_fontWidth, m_lineHeight);
}

QRect Widget::genInputTextRect(int i, int j)
{
    int y = i * m_lineHeight * 2 + m_lineHeight;
    int x = j * m_fontWidth;
    return QRect(x, y, m_fontWidth, m_lineHeight);
}

QLineF Widget::genCursorLine(int i, int j)
{
    int y = i * m_lineHeight * 2 + m_lineHeight;
    int x = j * m_fontWidth;
    return QLineF(
                x + 1,
                y,
                x + 1,
                y + m_lineHeight - 2
                );
}

void Widget::drawWrongChar(QPainter& painter, int i, int j, QChar targetCh, QChar inputCh)
{
    painter.save();
    painter.setPen(Qt::red);
    auto targetRect = genTargetTextRect(i, j);
    painter.drawText(targetRect, Qt::AlignCenter, QString(targetCh));
    auto inputRect = genInputTextRect(i, j);
    painter.drawText(inputRect, Qt::AlignCenter, QString(inputCh));
    painter.restore();
}

void Widget::drawCorrectChar(QPainter& painter, int i, int j, QChar ch)
{
    painter.save();
    painter.setPen(Qt::gray);
    auto targetRect = genTargetTextRect(i, j);
    painter.drawText(targetRect, Qt::AlignCenter, QString(ch));
    auto inputRect = genInputTextRect(i, j);
    painter.drawText(inputRect, Qt::AlignCenter, QString(ch));
    painter.restore();
}

void Widget::drawCursor(QPainter &painter)
{
    if (m_cursorShow) {
        int i = m_input.length() / m_eachLineCharCount;
        int j = m_input.length() % m_eachLineCharCount;
        painter.drawLine(genCursorLine(i, j));
    }
    m_cursorShow = !m_cursorShow;
}

void Widget::nextPageJudge()
{
    if (m_pageNum == m_pageText.length()) {
        return;
    }
    if (m_input.length() == m_text.length()) {
        m_pageNum++;
        m_input.clear();
        m_text = m_pageText[m_pageNum];
    }
}

猜你喜欢

转载自blog.csdn.net/qq_32768743/article/details/89005967