diff --git a/doc/README.md b/doc/README.md new file mode 100644 index 0000000..dc45f65 --- /dev/null +++ b/doc/README.md @@ -0,0 +1,2 @@ +# teamwork-project + diff --git a/src/examwidget.cpp b/src/examwidget.cpp new file mode 100644 index 0000000..50ef9fc --- /dev/null +++ b/src/examwidget.cpp @@ -0,0 +1,213 @@ +#include "examwidget.h" +#include +#include +#include + +ExamWidget::ExamWidget(QWidget *parent) : QWidget(parent), currentQuestion(0), totalQuestions(0) +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + // 进度标签 + progressLabel = new QLabel(); + progressLabel->setAlignment(Qt::AlignCenter); + progressLabel->setStyleSheet("font-size: 16px; font-weight: bold; margin: 20px; color: #2c3e50;"); + + // 题目区域 + QGroupBox *questionGroup = new QGroupBox("题目"); + questionGroup->setStyleSheet("QGroupBox {" + "font-size: 16px;" + "font-weight: bold;" + "margin-top: 10px;" + "}" + "QGroupBox::title {" + "subcontrol-origin: margin;" + "subcontrol-position: top center;" + "padding: 0 5px;" + "}"); + + QVBoxLayout *questionLayout = new QVBoxLayout(questionGroup); + + questionLabel = new QLabel(); + questionLabel->setWordWrap(true); + questionLabel->setStyleSheet("font-size: 18px; margin: 20px; padding: 10px; background-color: #f8f9fa; border-radius: 5px;"); + questionLabel->setAlignment(Qt::AlignCenter); + questionLabel->setMinimumHeight(80); + + questionLayout->addWidget(questionLabel); + + // 选项区域 + QGroupBox *optionsGroup = new QGroupBox("请选择答案"); + optionsGroup->setStyleSheet("QGroupBox {" + "font-size: 16px;" + "font-weight: bold;" + "margin-top: 10px;" + "}" + "QGroupBox::title {" + "subcontrol-origin: margin;" + "subcontrol-position: top center;" + "padding: 0 5px;" + "}"); + + QVBoxLayout *optionsLayout = new QVBoxLayout(optionsGroup); + optionGroup = new QButtonGroup(this); + + for (int i = 0; i < 4; ++i) { + optionButtons[i] = new QRadioButton(); + optionButtons[i]->setStyleSheet("QRadioButton {" + "font-size: 14px;" + "margin: 8px;" + "padding: 8px;" + "}" + "QRadioButton::indicator {" + "width: 20px;" + "height: 20px;" + "}"); + optionGroup->addButton(optionButtons[i], i); + optionsLayout->addWidget(optionButtons[i]); + } + + // 按钮区域 + QWidget *buttonWidget = new QWidget(); + QHBoxLayout *buttonLayout = new QHBoxLayout(buttonWidget); + + nextButton = new QPushButton("下一题"); + nextButton->setStyleSheet("QPushButton {" + "background-color: #3498db;" + "color: white;" + "border: none;" + "padding: 10px 20px;" + "font-size: 14px;" + "border-radius: 5px;" + "}" + "QPushButton:hover {" + "background-color: #2980b9;" + "}"); + nextButton->setFixedWidth(120); + + submitButton = new QPushButton("提交试卷"); + submitButton->setStyleSheet("QPushButton {" + "background-color: #e74c3c;" + "color: white;" + "border: none;" + "padding: 10px 20px;" + "font-size: 14px;" + "border-radius: 5px;" + "}" + "QPushButton:hover {" + "background-color: #c0392b;" + "}"); + submitButton->setFixedWidth(120); + submitButton->setVisible(false); + + buttonLayout->addStretch(); + buttonLayout->addWidget(nextButton); + buttonLayout->addSpacing(10); + buttonLayout->addWidget(submitButton); + buttonLayout->addStretch(); + + // 添加到主布局 + mainLayout->addWidget(progressLabel); + mainLayout->addWidget(questionGroup); + mainLayout->addWidget(optionsGroup); + mainLayout->addSpacing(20); + mainLayout->addWidget(buttonWidget); + mainLayout->addStretch(); + + // 连接信号槽 + connect(nextButton, &QPushButton::clicked, this, &ExamWidget::onNextClicked); + connect(submitButton, &QPushButton::clicked, this, &ExamWidget::onSubmitClicked); +} + +void ExamWidget::startExam(Grade grade, int questionCount) +{ + questionGenerator.setGrade(grade); + questions = questionGenerator.generateQuestions(questionCount); + totalQuestions = questionCount; + currentQuestion = 0; + userAnswers.clear(); + correctAnswers.clear(); + + // 生成正确答案(随机) + std::random_device rd; + std::mt19937 gen(rd()); + std::uniform_int_distribution<> dis(0, 3); + + for (int i = 0; i < totalQuestions; ++i) { + correctAnswers.push_back(dis(gen)); + } + + showQuestion(0); +} + +void ExamWidget::showQuestion(int index) +{ + if (index < totalQuestions) { + currentQuestion = index; + progressLabel->setText(QString("第 %1 题 / 共 %2 题").arg(index + 1).arg(totalQuestions)); + + // 显示题目 + QString questionText = QString::fromStdWString(questions[index]); + questionLabel->setText(questionText); + + // 生成选项 + generateOptions(); + + // 清除选择 + optionGroup->setExclusive(false); + for (int i = 0; i < 4; ++i) { + optionButtons[i]->setChecked(false); + } + optionGroup->setExclusive(true); + + // 更新按钮状态 + nextButton->setVisible(index < totalQuestions - 1); + submitButton->setVisible(index == totalQuestions - 1); + } +} + +void ExamWidget::generateOptions() +{ + // 简单实现:一个正确答案,三个随机错误答案 + int correctIndex = correctAnswers[currentQuestion]; + + for (int i = 0; i < 4; ++i) { + if (i == correctIndex) { + optionButtons[i]->setText("正确答案"); + } else { + optionButtons[i]->setText(QString("选项 %1").arg(i + 1)); + } + } +} + +void ExamWidget::onNextClicked() +{ + int selected = optionGroup->checkedId(); + if (selected == -1) { + QMessageBox::warning(this, "提示", "请选择一个答案"); + return; + } + + userAnswers.push_back(selected); + showQuestion(currentQuestion + 1); +} + +void ExamWidget::onSubmitClicked() +{ + int selected = optionGroup->checkedId(); + if (selected == -1) { + QMessageBox::warning(this, "提示", "请选择一个答案"); + return; + } + + userAnswers.push_back(selected); + + // 计算分数 + int score = 0; + for (int i = 0; i < totalQuestions; ++i) { + if (userAnswers[i] == correctAnswers[i]) { + score++; + } + } + + emit examFinished(score, totalQuestions); +} diff --git a/src/examwidget.h b/src/examwidget.h new file mode 100644 index 0000000..f5c90bd --- /dev/null +++ b/src/examwidget.h @@ -0,0 +1,49 @@ +#ifndef EXAMWIDGET_H +#define EXAMWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include "questiongenerator.h" +#include "user.h" + +class ExamWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ExamWidget(QWidget *parent = nullptr); + void startExam(Grade grade, int questionCount); + +signals: + void examFinished(int score, int total); + +private slots: + void onNextClicked(); + void onSubmitClicked(); + +private: + void showQuestion(int index); + void generateOptions(); + + QLabel *questionLabel; + QLabel *progressLabel; + QButtonGroup *optionGroup; + QRadioButton *optionButtons[4]; + QPushButton *nextButton; + QPushButton *submitButton; + + QuestionGenerator questionGenerator; + std::vector questions; + std::vector userAnswers; + std::vector correctAnswers; + int currentQuestion; + int totalQuestions; +}; + +#endif diff --git a/src/loginwidget.cpp b/src/loginwidget.cpp new file mode 100644 index 0000000..c4f9339 --- /dev/null +++ b/src/loginwidget.cpp @@ -0,0 +1,61 @@ +#include "loginwidget.h" + +LoginWidget::LoginWidget(QWidget *parent) : QWidget(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + + // 标题 + QLabel *titleLabel = new QLabel("数学学习软件 - 登录"); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setStyleSheet("font-size: 20px; font-weight: bold; margin: 20px;"); + + // 用户名输入 + QLabel *usernameLabel = new QLabel("用户名:"); + usernameEdit = new QLineEdit(); + + // 密码输入 + QLabel *passwordLabel = new QLabel("密码:"); + passwordEdit = new QLineEdit(); + passwordEdit->setEchoMode(QLineEdit::Password); + + // 按钮 + loginButton = new QPushButton("登录"); + registerButton = new QPushButton("注册新账号"); + + // 添加到布局 + layout->addWidget(titleLabel); + layout->addWidget(usernameLabel); + layout->addWidget(usernameEdit); + layout->addWidget(passwordLabel); + layout->addWidget(passwordEdit); + layout->addWidget(loginButton); + layout->addWidget(registerButton); + + // 连接信号槽 + connect(loginButton, &QPushButton::clicked, this, &LoginWidget::onLoginClicked); + connect(registerButton, &QPushButton::clicked, this, &LoginWidget::onRegisterClicked); +} + +void LoginWidget::onLoginClicked() +{ + QString username = usernameEdit->text(); + QString password = passwordEdit->text(); + + if (username.isEmpty() || password.isEmpty()) { + QMessageBox::warning(this, "输入错误", "请输入用户名和密码"); + return; + } + + User* user = userManager.authenticateUser(username.toStdWString(), + password.toStdWString()); + if (user) { + emit loginSuccess(user); + } else { + QMessageBox::warning(this, "登录失败", "用户名或密码错误"); + } +} + +void LoginWidget::onRegisterClicked() +{ + emit showRegister(); +} diff --git a/src/loginwidget.h b/src/loginwidget.h new file mode 100644 index 0000000..a1929f0 --- /dev/null +++ b/src/loginwidget.h @@ -0,0 +1,36 @@ +#ifndef LOGINWIDGET_H +#define LOGINWIDGET_H + + +#include +#include +#include +#include +#include +#include +#include "usermanage.h" + +class LoginWidget : public QWidget +{ + Q_OBJECT + +public: + explicit LoginWidget(QWidget *parent = nullptr); + +signals: + void loginSuccess(User* user); + void showRegister(); + +private slots: + void onLoginClicked(); + void onRegisterClicked(); + +private: + QLineEdit *usernameEdit; + QLineEdit *passwordEdit; + QPushButton *loginButton; + QPushButton *registerButton; + UserManager userManager; +}; + +#endif diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..7b89e2d --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,17 @@ +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + // 设置应用程序信息 + app.setApplicationName("数学学习软件"); + app.setApplicationVersion("1.0"); + app.setOrganizationName("软件工程学院"); + + MainWindow window; + window.show(); + + return app.exec(); +} diff --git a/src/mainmenuwidget.cpp b/src/mainmenuwidget.cpp new file mode 100644 index 0000000..f8cb0b5 --- /dev/null +++ b/src/mainmenuwidget.cpp @@ -0,0 +1,115 @@ +#include "mainmenuwidget.h" +#include + +MainMenuWidget::MainMenuWidget(QWidget *parent) : QWidget(parent) +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + // 标题和欢迎信息 + QLabel *titleLabel = new QLabel("数学学习软件"); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setStyleSheet("font-size: 24px; font-weight: bold; margin: 30px; color: #2c3e50;"); + + welcomeLabel = new QLabel("欢迎使用数学学习软件"); + welcomeLabel->setAlignment(Qt::AlignCenter); + welcomeLabel->setStyleSheet("font-size: 18px; margin: 20px; color: #34495e;"); + + userInfoLabel = new QLabel(); + userInfoLabel->setAlignment(Qt::AlignCenter); + userInfoLabel->setStyleSheet("font-size: 14px; margin: 10px; color: #7f8c8d;"); + + // 设置区域 + QGroupBox *settingsGroup = new QGroupBox("考试设置"); + settingsGroup->setStyleSheet("QGroupBox {" + "font-size: 16px;" + "font-weight: bold;" + "margin-top: 10px;" + "}" + "QGroupBox::title {" + "subcontrol-origin: margin;" + "subcontrol-position: top center;" + "padding: 0 5px;" + "}"); + + QVBoxLayout *settingsLayout = new QVBoxLayout(settingsGroup); + + // 年级选择 + QWidget *gradeWidget = new QWidget(); + QHBoxLayout *gradeLayout = new QHBoxLayout(gradeWidget); + QLabel *gradeLabel = new QLabel("选择年级:"); + gradeLabel->setStyleSheet("font-size: 14px;"); + gradeComboBox = new QComboBox(); + gradeComboBox->addItem("小学"); + gradeComboBox->addItem("初中"); + gradeComboBox->addItem("高中"); + gradeComboBox->setStyleSheet("padding: 8px; font-size: 14px;"); + gradeLayout->addWidget(gradeLabel); + gradeLayout->addWidget(gradeComboBox); + gradeLayout->addStretch(); + + // 题目数量 + QWidget *countWidget = new QWidget(); + QHBoxLayout *countLayout = new QHBoxLayout(countWidget); + QLabel *countLabel = new QLabel("题目数量:"); + countLabel->setStyleSheet("font-size: 14px;"); + questionCountSpinBox = new QSpinBox(); + questionCountSpinBox->setRange(10, 30); + questionCountSpinBox->setValue(15); + questionCountSpinBox->setStyleSheet("padding: 8px; font-size: 14px;"); + countLayout->addWidget(countLabel); + countLayout->addWidget(questionCountSpinBox); + countLayout->addStretch(); + + // 开始按钮 + startButton = new QPushButton("开始考试"); + startButton->setStyleSheet("QPushButton {" + "background-color: #e74c3c;" + "color: white;" + "border: none;" + "padding: 12px 30px;" + "font-size: 16px;" + "border-radius: 5px;" + "}" + "QPushButton:hover {" + "background-color: #c0392b;" + "}"); + startButton->setFixedSize(150, 50); + + // 添加到设置布局 + settingsLayout->addWidget(gradeWidget); + settingsLayout->addWidget(countWidget); + settingsLayout->addSpacing(20); + settingsLayout->addWidget(startButton, 0, Qt::AlignCenter); + + // 添加到主布局 + mainLayout->addWidget(titleLabel); + mainLayout->addWidget(welcomeLabel); + mainLayout->addWidget(userInfoLabel); + mainLayout->addSpacing(20); + mainLayout->addWidget(settingsGroup); + mainLayout->addStretch(); + + // 连接信号槽 + connect(startButton, &QPushButton::clicked, this, &MainMenuWidget::onStartExamClicked); +} + +void MainMenuWidget::setUserInfo(const std::wstring& username, const std::wstring& grade) +{ + QString userInfo = QString("当前用户: %1 | 年级: %2") + .arg(QString::fromStdWString(username)) + .arg(QString::fromStdWString(grade)); + userInfoLabel->setText(userInfo); + + // 设置年级选择框 + QString gradeStr = QString::fromStdWString(grade); + int index = gradeComboBox->findText(gradeStr); + if (index >= 0) { + gradeComboBox->setCurrentIndex(index); + } +} + +void MainMenuWidget::onStartExamClicked() +{ + int questionCount = questionCountSpinBox->value(); + emit startExam(questionCount); +} diff --git a/src/mainmenuwidget.h b/src/mainmenuwidget.h new file mode 100644 index 0000000..b1563b1 --- /dev/null +++ b/src/mainmenuwidget.h @@ -0,0 +1,35 @@ +#ifndef MAINMENUWIDGET_H +#define MAINMENUWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class MainMenuWidget : public QWidget +{ + Q_OBJECT + +public: + explicit MainMenuWidget(QWidget *parent = nullptr); + void setUserInfo(const std::wstring& username, const std::wstring& grade); + +signals: + void startExam(int questionCount); + +private slots: + void onStartExamClicked(); + +private: + QLabel *welcomeLabel; + QLabel *userInfoLabel; + QComboBox *gradeComboBox; + QSpinBox *questionCountSpinBox; + QPushButton *startButton; +}; + +#endif diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..bd56583 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,82 @@ +#include "mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), currentUser(nullptr) +{ + setWindowTitle("中小学数学学习软件"); + setFixedSize(600, 400); + + // 创建堆叠窗口 + stackedWidget = new QStackedWidget(this); + setCentralWidget(stackedWidget); + + // 创建各个界面 + loginWidget = new LoginWidget(); + registerWidget = new RegisterWidget(); + mainMenuWidget = new MainMenuWidget(); + examWidget = new ExamWidget(); + resultWidget = new ResultWidget(); + + // 添加到堆叠窗口 + stackedWidget->addWidget(loginWidget); + stackedWidget->addWidget(registerWidget); + stackedWidget->addWidget(mainMenuWidget); + stackedWidget->addWidget(examWidget); + stackedWidget->addWidget(resultWidget); + + // 连接信号槽 + connect(loginWidget, &LoginWidget::loginSuccess, this, &MainWindow::onUserLoggedIn); + connect(loginWidget, &LoginWidget::showRegister, this, &MainWindow::showRegister); + connect(registerWidget, &RegisterWidget::showLogin, this, &MainWindow::showLogin); + connect(registerWidget, &RegisterWidget::registerSuccess, this, &MainWindow::onUserLoggedIn); + connect(mainMenuWidget, &MainMenuWidget::startExam, this, &MainWindow::showExam); + connect(examWidget, &ExamWidget::examFinished, this, &MainWindow::showResult); + connect(resultWidget, &ResultWidget::backToMenu, this, &MainWindow::showMainMenu); + connect(resultWidget, &ResultWidget::startNewExam, this, &MainWindow::showMainMenu); + + // 显示登录界面 + showLogin(); +} + +MainWindow::~MainWindow() +{ +} + +void MainWindow::showLogin() +{ + stackedWidget->setCurrentWidget(loginWidget); +} + +void MainWindow::showRegister() +{ + stackedWidget->setCurrentWidget(registerWidget); +} + +void MainWindow::showMainMenu() +{ + if (currentUser) { + mainMenuWidget->setUserInfo(currentUser->getUsername(), + currentUser->getGradeString()); + stackedWidget->setCurrentWidget(mainMenuWidget); + } +} + +void MainWindow::showExam(int questionCount) +{ + if (currentUser) { + examWidget->startExam(currentUser->getGrade(), questionCount); + stackedWidget->setCurrentWidget(examWidget); + } +} + +void MainWindow::showResult(int score, int total) +{ + resultWidget->setResult(score, total); + stackedWidget->setCurrentWidget(resultWidget); +} + +void MainWindow::onUserLoggedIn(User* user) +{ + currentUser = user; + showMainMenu(); +} diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 0000000..988d647 --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,40 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include "loginwidget.h" +#include "registerwidget.h" +#include "mainmenuwidget.h" +#include "examwidget.h" +#include "resultwidget.h" +#include "usermanage.h" + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + +private slots: + void showLogin(); + void showRegister(); + void showMainMenu(); + void showExam(int questionCount); + void showResult(int score, int total); + void onUserLoggedIn(User* user); + +private: + QStackedWidget *stackedWidget; + LoginWidget *loginWidget; + RegisterWidget *registerWidget; + MainMenuWidget *mainMenuWidget; + ExamWidget *examWidget; + ResultWidget *resultWidget; + UserManager userManager; + User *currentUser; +}; + +#endif diff --git a/src/registerwidget.cpp b/src/registerwidget.cpp new file mode 100644 index 0000000..b80673c --- /dev/null +++ b/src/registerwidget.cpp @@ -0,0 +1,113 @@ +#include "registerwidget.h" + +RegisterWidget::RegisterWidget(QWidget *parent) : QWidget(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + + // 标题 + QLabel *titleLabel = new QLabel("用户注册"); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setStyleSheet("font-size: 20px; font-weight: bold; margin: 20px;"); + + // 邮箱输入 + QLabel *emailLabel = new QLabel("邮箱:"); + emailEdit = new QLineEdit(); + + // 注册码 + QLabel *codeLabel = new QLabel("注册码:"); + registerCodeEdit = new QLineEdit(); + registerCodeEdit->setText(generateRegisterCode()); + registerCodeEdit->setReadOnly(true); + + // 密码输入 + QLabel *passwordLabel = new QLabel("密码 (6-10位,包含大小写字母和数字):"); + passwordEdit = new QLineEdit(); + passwordEdit->setEchoMode(QLineEdit::Password); + + // 确认密码 + QLabel *confirmPasswordLabel = new QLabel("确认密码:"); + confirmPasswordEdit = new QLineEdit(); + confirmPasswordEdit->setEchoMode(QLineEdit::Password); + + // 按钮 + registerButton = new QPushButton("注册"); + backButton = new QPushButton("返回登录"); + + // 添加到布局 + layout->addWidget(titleLabel); + layout->addWidget(emailLabel); + layout->addWidget(emailEdit); + layout->addWidget(codeLabel); + layout->addWidget(registerCodeEdit); + layout->addWidget(passwordLabel); + layout->addWidget(passwordEdit); + layout->addWidget(confirmPasswordLabel); + layout->addWidget(confirmPasswordEdit); + layout->addWidget(registerButton); + layout->addWidget(backButton); + + // 连接信号槽 + connect(registerButton, &QPushButton::clicked, this, &RegisterWidget::onRegisterClicked); + connect(backButton, &QPushButton::clicked, this, &RegisterWidget::onBackClicked); +} + +void RegisterWidget::onRegisterClicked() +{ + QString email = emailEdit->text(); + QString password = passwordEdit->text(); + QString confirmPassword = confirmPasswordEdit->text(); + + // 邮箱格式验证 + QRegularExpression emailRegex(R"(^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)"); + if (!emailRegex.match(email).hasMatch()) { + QMessageBox::warning(this, "输入错误", "请输入有效的邮箱地址"); + return; + } + + // 密码验证 + if (password != confirmPassword) { + QMessageBox::warning(this, "输入错误", "两次输入的密码不一致"); + return; + } + + if (!validatePassword(password)) { + QMessageBox::warning(this, "输入错误", + "密码必须为6-10位,且包含大小写字母和数字"); + return; + } + + QMessageBox::information(this, "注册成功", "注册成功!"); + emit registerSuccess(); +} + +void RegisterWidget::onBackClicked() +{ + emit showLogin(); +} + +bool RegisterWidget::validatePassword(const QString &password) +{ + if (password.length() < 6 || password.length() > 10) { + return false; + } + + bool hasUpper = false, hasLower = false, hasDigit = false; + for (QChar ch : password) { + if (ch.isUpper()) hasUpper = true; + else if (ch.isLower()) hasLower = true; + else if (ch.isDigit()) hasDigit = true; + } + + return hasUpper && hasLower && hasDigit; +} + +QString RegisterWidget::generateRegisterCode() +{ + const QString possibleChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + QString code; + for (int i = 0; i < 8; ++i) { + int index = qrand() % possibleChars.length(); + code.append(possibleChars.at(index)); + } + return code; +} diff --git a/src/registerwidget.h b/src/registerwidget.h new file mode 100644 index 0000000..865ddd9 --- /dev/null +++ b/src/registerwidget.h @@ -0,0 +1,40 @@ +#ifndef REGISTERWIDGET_H +#define REGISTERWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include + +class RegisterWidget : public QWidget +{ + Q_OBJECT + +public: + explicit RegisterWidget(QWidget *parent = nullptr); + +signals: + void registerSuccess(); + void showLogin(); + +private slots: + void onRegisterClicked(); + void onBackClicked(); + +private: + QLineEdit *emailEdit; + QLineEdit *registerCodeEdit; + QLineEdit *passwordEdit; + QLineEdit *confirmPasswordEdit; + QPushButton *registerButton; + QPushButton *backButton; + + bool validatePassword(const QString &password); + QString generateRegisterCode(); +}; + +#endif diff --git a/src/resultwidget.cpp b/src/resultwidget.cpp new file mode 100644 index 0000000..23f9f3e --- /dev/null +++ b/src/resultwidget.cpp @@ -0,0 +1,115 @@ +#include "resultwidget.h" + +ResultWidget::ResultWidget(QWidget *parent) : QWidget(parent) +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + + // 标题 + QLabel *titleLabel = new QLabel("考试结果"); + titleLabel->setAlignment(Qt::AlignCenter); + titleLabel->setStyleSheet("font-size: 24px; font-weight: bold; margin: 30px; color: #2c3e50;"); + + // 结果区域 + QWidget *resultWidget = new QWidget(); + QVBoxLayout *resultLayout = new QVBoxLayout(resultWidget); + resultLayout->setContentsMargins(50, 30, 50, 30); + + resultLabel = new QLabel("考试完成!"); + resultLabel->setAlignment(Qt::AlignCenter); + resultLabel->setStyleSheet("font-size: 20px; margin: 20px; color: #34495e;"); + + scoreLabel = new QLabel(); + scoreLabel->setAlignment(Qt::AlignCenter); + scoreLabel->setStyleSheet("font-size: 36px; font-weight: bold; margin: 20px; color: #e74c3c;"); + + percentageLabel = new QLabel(); + percentageLabel->setAlignment(Qt::AlignCenter); + percentageLabel->setStyleSheet("font-size: 18px; margin: 10px; color: #7f8c8d;"); + + // 按钮区域 + QWidget *buttonWidget = new QWidget(); + QHBoxLayout *buttonLayout = new QHBoxLayout(buttonWidget); + + backButton = new QPushButton("返回主菜单"); + backButton->setStyleSheet("QPushButton {" + "background-color: #95a5a6;" + "color: white;" + "border: none;" + "padding: 10px 20px;" + "font-size: 14px;" + "border-radius: 5px;" + "}" + "QPushButton:hover {" + "background-color: #7f8c8d;" + "}"); + backButton->setFixedWidth(120); + + newExamButton = new QPushButton("继续做题"); + newExamButton->setStyleSheet("QPushButton {" + "background-color: #3498db;" + "color: white;" + "border: none;" + "padding: 10px 20px;" + "font-size: 14px;" + "border-radius: 5px;" + "}" + "QPushButton:hover {" + "background-color: #2980b9;" + "}"); + newExamButton->setFixedWidth(120); + + buttonLayout->addStretch(); + buttonLayout->addWidget(backButton); + buttonLayout->addSpacing(20); + buttonLayout->addWidget(newExamButton); + buttonLayout->addStretch(); + + // 添加到结果布局 + resultLayout->addWidget(resultLabel); + resultLayout->addWidget(scoreLabel); + resultLayout->addWidget(percentageLabel); + resultLayout->addSpacing(30); + resultLayout->addWidget(buttonWidget); + + // 添加到主布局 + mainLayout->addWidget(titleLabel); + mainLayout->addWidget(resultWidget); + mainLayout->addStretch(); + + // 连接信号槽 + connect(backButton, &QPushButton::clicked, this, &ResultWidget::onBackClicked); + connect(newExamButton, &QPushButton::clicked, this, &ResultWidget::onNewExamClicked); +} + +void ResultWidget::setResult(int score, int total) +{ + double percentage = (double)score / total * 100; + + scoreLabel->setText(QString("%1 / %2").arg(score).arg(total)); + percentageLabel->setText(QString("正确率: %1%").arg(percentage, 0, 'f', 1)); + + // 根据分数显示不同的评价 + if (percentage >= 90) { + resultLabel->setText("优秀!你的表现非常出色!"); + resultLabel->setStyleSheet("font-size: 20px; margin: 20px; color: #27ae60;"); + } else if (percentage >= 70) { + resultLabel->setText("良好!继续努力!"); + resultLabel->setStyleSheet("font-size: 20px; margin: 20px; color: #f39c12;"); + } else if (percentage >= 60) { + resultLabel->setText("及格!还有提升空间!"); + resultLabel->setStyleSheet("font-size: 20px; margin: 20px; color: #e67e22;"); + } else { + resultLabel->setText("需要加油!再多练习一下吧!"); + resultLabel->setStyleSheet("font-size: 20px; margin: 20px; color: #e74c3c;"); + } +} + +void ResultWidget::onBackClicked() +{ + emit backToMenu(); +} + +void ResultWidget::onNewExamClicked() +{ + emit startNewExam(); +} diff --git a/src/resultwidget.h b/src/resultwidget.h new file mode 100644 index 0000000..0343e7e --- /dev/null +++ b/src/resultwidget.h @@ -0,0 +1,34 @@ +#ifndef RESULTWIDGET_H +#define RESULTWIDGET_H + +#include +#include +#include +#include +#include + +class ResultWidget : public QWidget +{ + Q_OBJECT + +public: + explicit ResultWidget(QWidget *parent = nullptr); + void setResult(int score, int total); + +signals: + void backToMenu(); + void startNewExam(); + +private slots: + void onBackClicked(); + void onNewExamClicked(); + +private: + QLabel *resultLabel; + QLabel *scoreLabel; + QLabel *percentageLabel; + QPushButton *backButton; + QPushButton *newExamButton; +}; + +#endif