@ -0,0 +1,2 @@
|
||||
# teamwork-project
|
||||
|
||||
@ -0,0 +1,213 @@
|
||||
#include "examwidget.h"
|
||||
#include <QMessageBox>
|
||||
#include <random>
|
||||
#include <QGroupBox>
|
||||
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
#ifndef EXAMWIDGET_H
|
||||
#define EXAMWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QButtonGroup>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <vector>
|
||||
#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<std::wstring> questions;
|
||||
std::vector<int> userAnswers;
|
||||
std::vector<int> correctAnswers;
|
||||
int currentQuestion;
|
||||
int totalQuestions;
|
||||
};
|
||||
|
||||
#endif
|
||||
@ -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();
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
#ifndef LOGINWIDGET_H
|
||||
#define LOGINWIDGET_H
|
||||
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#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
|
||||
@ -0,0 +1,17 @@
|
||||
#include <QApplication>
|
||||
#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();
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
#include "mainmenuwidget.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
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);
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
#ifndef MAINMENUWIDGET_H
|
||||
#define MAINMENUWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QComboBox>
|
||||
#include <QSpinBox>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QGroupBox>
|
||||
|
||||
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
|
||||
@ -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();
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QStackedWidget>
|
||||
#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
|
||||
@ -0,0 +1,40 @@
|
||||
#ifndef REGISTERWIDGET_H
|
||||
#define REGISTERWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionValidator>
|
||||
|
||||
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
|
||||
@ -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();
|
||||
}
|
||||
@ -0,0 +1,34 @@
|
||||
#ifndef RESULTWIDGET_H
|
||||
#define RESULTWIDGET_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
|
||||
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
|
||||
Loading…
Reference in new issue