Qt/C++项目 学生成绩管理系统

  1. 直观的 QT 图形界面:采用 QT 构建的用户友好界面,提供清晰的菜单选项,确保用户轻松导航和访问各项功能。

  2. 数据库驱动的数据存储:系统使用数据库技术安全高效地存储学生信息,保障数据的完整性和可靠性。

  3. 全面的基本功能:包括添加、删除、修改和查询学生数据,支持模糊查找,便捷地获取所需信息。

  4. 高级统计功能:系统具备先进的数据统计功能,提供图形化展示,使成绩分析直观易懂,支持对学生表现的全面分析。

  5. 数据的批量导入和导出:提供批量导入学生信息的能力,方便从其他系统迁移数据;同时支持将数据以 CSV 格式导出,便于备份或在其他应用中使用。

  6. 内置帮助文档:配备完善的帮助文档,用户可通过按 F1 快捷键获取即时帮助,轻松了解系统的使用方法和功能细节。

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QPushButton>
#include <QLineEdit>
#include <QTableWidget>
#include <QDoubleSpinBox>
#include <QRadioButton>
#include <QLabel>
#include <QtCharts>
#include "studentmanager.h"
#include "student.h"using namespace QtCharts;class MainWindow : public QMainWindow {Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);private:QPushButton *addButton;QPushButton *deleteButton;QPushButton *updateButton;QLineEdit *nameEdit;QDoubleSpinBox *scoreSpin;QTableWidget *studentTable;QPushButton *searchButton;QRadioButton *sortAscButton;QRadioButton *sortDescButton;QLineEdit *searchEdit;QLabel *analysisLabel;QChartView *chartView;QPushButton *exportButton;QPushButton *importButton;StudentManager studentManager;void setupUi();void connectSignalsSlots();void refreshStudentTable();void refreshStudentTable(const QList<Student>& students);void updateChart();QChart* createChart();int getNextStudentId();void updateAnalysis(const QList<Student>& students);void importData();void exportData();private slots:void addStudent();void deleteStudent();void updateStudent();void searchStudents();void sortStudents();void onExportButtonClicked();void onImportButtonClicked();};#endif // MAINWINDOW_H

/*** @brief 学生成绩管理系统 20240408* @author VX:Cgsjed*/
#include "mainwindow.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QMessageBox>
#include <QStringList>
#include <QHeaderView>
# define tc(a) QString::fromLocal8Bit(a)
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {setupUi();connectSignalsSlots();refreshStudentTable();
}void MainWindow::setupUi() {QWidget *centralWidget = new QWidget(this);QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget);QHBoxLayout *inputLayout = new QHBoxLayout();nameEdit = new QLineEdit();scoreSpin = new QDoubleSpinBox();addButton = new QPushButton(tc("添加"));deleteButton = new QPushButton(tc("删除"));updateButton = new QPushButton(tc("刷新"));inputLayout->addWidget(new QLabel(tc("姓名")));inputLayout->addWidget(nameEdit);inputLayout->addWidget(new QLabel(tc("分数")));inputLayout->addWidget(scoreSpin);inputLayout->addWidget(addButton);inputLayout->addWidget(deleteButton);inputLayout->addWidget(updateButton);studentTable = new QTableWidget();studentTable->setColumnCount(3); // ID, Name, ScorestudentTable->setFixedWidth(300);QStringList headers = {tc("编号"), tc("姓名"), tc("分数")};studentTable->setHorizontalHeaderLabels(headers);studentTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);studentTable->setSortingEnabled(true);QHBoxLayout *searchLayout = new QHBoxLayout();searchButton = new QPushButton(tc("查询"));searchEdit = new QLineEdit();sortAscButton = new QRadioButton(tc("分数正序"));sortDescButton = new QRadioButton(tc("分数倒序"));sortAscButton->setChecked(true);exportButton = new QPushButton(tc("数据导出"), this);importButton = new QPushButton(tc("导入数据"), this);searchLayout->addWidget(exportButton);searchLayout->addWidget(importButton);searchLayout->addWidget(new QLabel(tc("输出查询的姓名")));searchLayout->addWidget(searchEdit);searchLayout->addWidget(searchButton);searchLayout->addWidget(sortAscButton);searchLayout->addWidget(sortDescButton);chartView = new QChartView(createChart());mainLayout->addLayout(inputLayout);mainLayout->addLayout(searchLayout);QHBoxLayout *searchLayout1 = new QHBoxLayout();searchLayout1->addWidget(studentTable);searchLayout1->addWidget(chartView);mainLayout->addLayout(searchLayout1);setCentralWidget(centralWidget);this->setWindowTitle(tc("学生成绩管理系统"));
}void MainWindow::connectSignalsSlots() {connect(addButton, &QPushButton::clicked, this, &MainWindow::addStudent);connect(deleteButton, &QPushButton::clicked, this, &MainWindow::deleteStudent);connect(updateButton, &QPushButton::clicked, this, &MainWindow::updateStudent);connect(searchButton, &QPushButton::clicked, this, &MainWindow::searchStudents);connect(sortAscButton, &QRadioButton::toggled, this, &MainWindow::sortStudents);connect(sortDescButton, &QRadioButton::toggled, this, &MainWindow::sortStudents);connect(exportButton, &QPushButton::clicked, this, &MainWindow::onExportButtonClicked);connect(importButton, &QPushButton::clicked, this, &MainWindow::onImportButtonClicked);}void MainWindow::addStudent() {QString name = nameEdit->text();double score = scoreSpin->value();if (name.isEmpty() || score < 0) {QMessageBox::warning(this, "Input Error", "Invalid name or score.");return;}Student student(getNextStudentId(), name, score);studentManager.addStudent(student);refreshStudentTable();updateChart();
}void MainWindow::deleteStudent() {int row = studentTable->currentRow();if (row == -1) {QMessageBox::warning(this, "Selection Error", "Please select a student to delete.");return;}int id = studentTable->item(row, 0)->text().toInt();studentManager.deleteStudent(id);refreshStudentTable();updateChart();
}void MainWindow::updateStudent()
{refreshStudentTable();
}void MainWindow::searchStudents() {QString name = searchEdit->text();auto students = studentManager.findStudentsByName(name);refreshStudentTable(students);updateChart();
}void MainWindow::sortStudents() {bool isAscending = sortAscButton->isChecked();studentTable->sortItems(2, isAscending ? Qt::AscendingOrder : Qt::DescendingOrder);
}void MainWindow::onExportButtonClicked()
{// 实现导出数据到文件的逻辑exportData();
}void MainWindow::onImportButtonClicked()
{// 实现从文件导入数据的逻辑importData();
}void MainWindow::refreshStudentTable() {auto students = studentManager.getAllStudents();refreshStudentTable(students);
}void MainWindow::refreshStudentTable(const QList<Student>& students) {studentTable->clearContents();studentTable->setRowCount(students.count());for (int i = 0; i < students.count(); ++i) {auto student = students[i];studentTable->setItem(i, 0, new QTableWidgetItem(QString::number(student.getId())));studentTable->setItem(i, 1, new QTableWidgetItem(student.getName()));studentTable->setItem(i, 2, new QTableWidgetItem(QString::number(student.getScore())));}studentTable->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);studentTable->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);studentTable->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
}void MainWindow::updateChart() {auto chart = createChart();chartView->setChart(chart);
}
QChart* MainWindow::createChart() {QBarSeries *series = new QBarSeries();QBarSet *set = new QBarSet(tc("及格线"));QStringList categories;// 从学生管理器获取数据并填充到柱状图中QList<Student> students = studentManager.getAllStudents();for (const Student &student : students) {*set << student.getScore();  // 将分数添加到柱状图categories << student.getName();  // 将学生名字添加到类别中}series->append(set);QChart *chart = new QChart();chart->addSeries(series);chart->setTitle(tc("班级成绩柱状图"));chart->setAnimationOptions(QChart::SeriesAnimations);QBarCategoryAxis *axisX = new QBarCategoryAxis();axisX->append(categories);  // 设置类别为学生姓名chart->addAxis(axisX, Qt::AlignBottom);series->attachAxis(axisX);QValueAxis *axisY = new QValueAxis();axisY->setRange(0, 100);axisY->setTickInterval(10);chart->addAxis(axisY, Qt::AlignLeft);series->attachAxis(axisY);// 在 60 分位置绘制一条横线作为及格线QLineSeries *passLine = new QLineSeries();passLine->append(QPointF(-5, 60));passLine->append(QPointF(students.count(), 60)); // 覆盖整个 X 轴范围QPen pen(Qt::red, 2, Qt::DashLine); // 红色虚线passLine->setPen(pen);chart->addSeries(passLine);passLine->attachAxis(axisX);passLine->attachAxis(axisY);chart->legend()->setVisible(true);chart->legend()->setAlignment(Qt::AlignBottom);return chart;
}int MainWindow::getNextStudentId() {auto students = studentManager.getAllStudents();int maxId = 0;for (auto &student : students) {if (student.getId() > maxId)maxId = student.getId();}return maxId + 1;
}void MainWindow::importData() {QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", tr("CSV (*.csv)"));if (fileName.isEmpty()) {return;}QFile file(fileName);if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {QMessageBox::warning(this, tr("Error"), tr("Unable to open file"));return;}QTextStream stream(&file);// 忽略第一行标题if (!stream.atEnd()) {stream.readLine();}QSet<QString> existingNames;for (const auto &student : studentManager.getAllStudents()) {existingNames.insert(student.getName());}int nextId = getNextStudentId();while (!stream.atEnd()) {QString line = stream.readLine();QStringList strList = line.split(",");if (strList.size() >= 3) {QString name = strList.at(1).trimmed().replace("\"", "");double score = strList.at(2).trimmed().replace("\"", "").toDouble();// 仅添加不存在的新名字if (!existingNames.contains(name)) {Student student(nextId++, name, score);studentManager.addStudent(student);existingNames.insert(name);}}}file.close();refreshStudentTable();updateChart();
}void MainWindow::exportData()
{QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("CSV (*.csv)"));if (fileName.isEmpty()) {return;}QFile file(fileName);if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {QMessageBox::warning(this, tr("Error"), tr("Unable to open file"));return;}QTextStream stream(&file);QStringList strList;// 写入标题for (int c = 0; c < studentTable->horizontalHeader()->count(); ++c) {strList << "\"" + studentTable->model()->headerData(c, Qt::Horizontal).toString() + "\"";}stream << strList.join(",") << "\n";// 写入数据for (int r = 0; r < studentTable->rowCount(); ++r) {strList.clear();for (int c = 0; c < studentTable->columnCount(); ++c) {strList << "\"" + studentTable->item(r, c)->text() + "\"";}stream << strList.join(",") << "\n";}file.close();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/601032.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

017——DS18B20驱动开发(基于I.MX6uLL)

目录 一、 模块介绍 1.1 简介 1.2 主要特点 1.3 存储器介绍 1.4 时序 1.5 命令 1.5.1 命令大全 1.5.2 命令使用 1.5.3 使用示例 1.6 原理图 二、 驱动程序 三、 应用程序 四、 测试 一、 模块介绍 1.1 简介 DS18B20 温度传感器具有线路简单、体积小的特点&…

MagicHut 工具分享

设计师必备工具 与全球一流设计师交流&#xff0c;分享在全世界的一流设计网站上展示作品&#xff0c;寻找灵感 免费拥有超过 20,000 TB 的设计师素材 免费下载行业设计工具&#xff0c;软件 其实是可以让你拥有魔法&#xff0c;免费使用&#xff0c;每天签到就行&#xff0c;…

2024/4/1—力扣—BiNode

代码实现&#xff1a; /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*/void convertBiNode_pro(struct TreeNode *root, struct TreeNode **p) {if (root) {convertBiNode_pro(roo…

Python—循环加强

1.使用循环打印等腰三角形 # 画三角形层数为n # 第i层有空格&#xff1a;n-i # 第i层有*&#xff1a;2*i-1 n int(input("层数&#xff1a;"))#层数n for i in range(1, n 1):#范围在1~n# 画空格for _ in range(1, n - i 1): # _不用显示&#xff0c;用于表示&a…

windows下使用的的数字取证工作工具套装:forensictools

推荐一套windows下使用的的数字取证工作工具套装&#xff1a;forensictools 部分工具包括&#xff1a; ▫️exiftool&#xff0c;一个命令行应用程序和 Perl 库&#xff0c;用于读写元信息。 ▫️YARA&#xff0c;一款开源工具&#xff0c;用于对恶意软件样本进行识别和分类。…

2024智能计算、大数据应用与信息科学国际会议(ICBDAIS2024)

2024智能计算、大数据应用与信息科学国际会议(ICBDAIS2024) 会议简介 智能计算、大数据应用与信息科学之间存在相互依存、相互促进的关系。智能计算和大数据应用的发展离不开信息科学的支持和推动&#xff0c;而信息科学的发展又需要智能计算和大数据应用的不断拓展和应用。智…

如何选择苹果iOS系统的企业签名分发平台

哈喽&#xff0c;大家好呀&#xff0c;淼淼有和大家见面啦&#xff0c;前两期讲了分发内测的一些相关知识&#xff0c;这一期咱们来聊聊企业签名分发平台的相关知识。最近移动应用市场的竞争一天比一天要激烈&#xff0c;许多做开发的小伙伴们都在为此发愁&#xff0c;愁着该怎…

Splatstudio 学习笔记

1. 3DGS 是全图的Render, 因此特地写了 full_images_datamanger.py 每个step 取出一张图像。 返回值是一张 全图的 RGB 和对应的 Camera 2. 3D GS 没有生成光线&#xff0c;因此 不需要指定near 和 far&#xff0c;即 collider是None。 但需要对3D 高斯球进行初始化&#xff…

Django检测到会话cookie中缺少HttpOnly属性手工复现

一、漏洞复现 会话cookie中缺少HttpOnly属性会导致攻击者可以通过程序(JS脚本等)获取到用户的cookie信息&#xff0c;造成用户cookie信息泄露&#xff0c;增加攻击者的跨站脚本攻击威胁。 第一步&#xff1a;复制URL&#xff1a;http://192.168.43.219在浏览器打开&#xff0c;…

【Linux C | 多线程编程】线程同步 | 互斥量

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a; 本文未经允许…

k8snode节点kubeadm join主节点失败,请问你们有什么好的办法吗?

K8S版本&#xff1a;1.20.9&#xff0c;docker也是1.20的 在网上找了&#xff0c;说是关闭交换区swap&#xff0c;这个也关了&#xff0c;防火墙也关了&#xff0c;现在kubelet无法启动&#xff0c;网上查了只有kubeadm init后kubelet才能启动&#xff0c;而init后10250端口会…

货物摆放-C++题解

计算本题前先了解一下约数 约数&#xff0c;又称因数。整数a除以整数b(b≠0) 除得的商正好是整数而没有余数&#xff0c;我们就说a能被b整除&#xff0c;或b能整除a。a称为b的倍数&#xff0c;b称为a的约数 然后首先要求出n的所有因数&#xff0c;因为题目需要满足的条件是nLWH…