/
spitsyn62
/
AcademicPerformance
Обзор
Документация
Войти
/
spitsyn62
/
AcademicPerformance
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
StudentTableModel.cpp
307 строк
7 KB
spitsyn62
create: AcademicPerformance.pro, main.cpp, MainWindow.cpp, MainWindow.h, MainWindow.ui, README.txt, StudentTableModel.cpp, StudentTableModel.h, Список студентов.csv
15 май 2026, 14:21
Верифицирован
15 май 2026, 14:21
b654f18
Код
Авторство
О чём код?
#include "studenttablemodel.h" #include "qbrush.h" #include "qcolor.h" #include <QFile> #include <QTextStream> StudentTableModel::StudentTableModel(QObject *parent) : QAbstractTableModel(parent) { } int StudentTableModel::rowCount(const QModelIndex &) const { return students_.size(); } int StudentTableModel::columnCount(const QModelIndex &) const { return 10; // ФИО + 7 лабораторных } QVariant StudentTableModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (index.row() >= students_.size()) return QVariant(); if (role == Qt::TextAlignmentRole && index.column() > 0) { return Qt::AlignCenter; } const Student &s = students_.at(index.row()); if (index.column() == 8) { bool allowed = isAllowed(s); if (role == Qt::DisplayRole) return allowed ? "да" : "нет"; if (role == Qt::BackgroundRole) { if (!allowed) return QBrush(QColor(255, 80, 80)); // ярко-красный else return QBrush(QColor(170, 255, 170)); // зелёный } if (role == Qt::TextAlignmentRole) return Qt::AlignCenter; return QVariant(); } if (index.column() == 0) { if (role == Qt::DisplayRole) return s.name; if (role == Qt::TextAlignmentRole) return Qt::AlignLeft; return QVariant(); } if (index.column() == 9) { double avg = averageScore(s); if (role == Qt::DisplayRole) return QString::number(avg, 'f', 2); // 2 знака после запятой if (role == Qt::TextAlignmentRole) return Qt::AlignCenter; // лёгкая визуализация по качеству if (role == Qt::BackgroundRole) { if (avg < 2.5) return QBrush(QColor(255, 150, 150)); // плохо if (avg < 4.0) return QBrush(QColor(255, 255, 180)); // средне return QBrush(QColor(170, 255, 170)); // хорошо } return QVariant(); } int value = s.labs.at(index.column() - 1); // ТЕКСТ if (role == Qt::DisplayRole) { if (value == 0) return "не сдана"; return value; } // В РЕЖИМЕ РЕДАКТИРОВАНИЯ показываем число if (role == Qt::EditRole) return value; // ЦВЕТ ФОНА if (role == Qt::BackgroundRole) { if (value == 0) return QBrush(QColor(255, 150, 150)); // красный if (value >= 1 && value <= 3) return QBrush(QColor(255, 255, 180)); // светло-жёлтый if (value == 4) return QBrush(QColor(240, 200, 120)); // охра if (value == 5) return QBrush(QColor(170, 255, 170)); // зелёный } return QVariant(); } QVariant StudentTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role != Qt::DisplayRole) return QVariant(); if (orientation == Qt::Horizontal) { if (section == 0) return "ФИО"; else if (section >= 1 && section <= 7) return QString("ЛР%1").arg(section); else if (section == 8) return "Допущен\nк экзамену"; else if (section == 9) return "Рекомендуемая\nоценка"; } return section + 1; } Qt::ItemFlags StudentTableModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::NoItemFlags; if (index.column() == 8 || index.column() == 9) return Qt::ItemIsSelectable | Qt::ItemIsEnabled; // Разрешаем редактировать лабораторные if (index.column() > 0) return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } bool StudentTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role != Qt::EditRole || !index.isValid()) return false; if (index.column() == 0) return false; bool ok; int val = value.toInt(&ok); if (!ok) return false; // Ограничение 0–5 if (val < 0 || val > 5) return false; Student &s = students_[index.row()]; s.labs[index.column() - 1] = val; emit dataChanged(index, index); // обновляем колонку допуска QModelIndex allowIndex = this->index(index.row(), 8); emit dataChanged(allowIndex, allowIndex); // средний балл QModelIndex avgIndex = this->index(index.row(), 9); emit dataChanged(avgIndex, avgIndex); return true; } void StudentTableModel::loadFromCsv(const QString &filePath) { beginResetModel(); students_.clear(); QFile file(filePath); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine().trimmed(); if (line.isEmpty()) continue; Student s; s.name = line; // инициализируем 7 лабораторных нулями s.labs = QVector<int>(7, 0); students_.append(s); } file.close(); } endResetModel(); } double StudentTableModel::averageScore(const Student &s) const { if (s.labs.isEmpty()) return 0.0; int sum = 0; for (int val : s.labs) sum += val; return static_cast<double>(sum) / s.labs.size(); } void StudentTableModel::saveToCsv(const QString &filePath) const { QFile file(filePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return; QTextStream out(&file); // заголовок out << "ФИО;ЛР1;ЛР2;ЛР3;ЛР4;ЛР5;ЛР6;ЛР7\n"; for (const Student &s : students_) { out << s.name; for (int val : s.labs) out << ";" << val; out << "\n"; } file.close(); } void StudentTableModel::loadFullCsv(const QString &filePath) { beginResetModel(); students_.clear(); QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { endResetModel(); return; } QTextStream in(&file); // пропускаем заголовок if (!in.atEnd()) in.readLine(); while (!in.atEnd()) { QString line = in.readLine().trimmed(); if (line.isEmpty()) continue; QStringList parts = line.split(";"); if (parts.size() < 8) continue; Student s; s.name = parts[0]; s.labs.clear(); for (int i = 1; i <= 7; ++i) { bool ok; int val = parts[i].toInt(&ok); s.labs.append(ok ? val : 0); } students_.append(s); } file.close(); endResetModel(); }