#include "mainwindow.h" #include #include #include #include #include #include #include #include #include //#include //#include //#include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { setupUI(); } MainWindow::~MainWindow() {} void MainWindow::setupUI() { QWidget *central = new QWidget(this); setCentralWidget(central); // 顶部菜单栏 QMenuBar *menuBar = this->menuBar(); fileMenu = menuBar->addMenu("文件(&F)"); // 快捷键 alt + F editMenu = menuBar->addMenu("编辑(&E)"); // 快捷键 alt + E // TODO // 左侧班级树控件 tree = new QTreeWidget; tree->setHeaderLabel("班级列表"); tree->setContextMenuPolicy(Qt::CustomContextMenu); // 显示学生信息控件 table = new QTableWidget; table->setColumnCount(5); table->setHorizontalHeaderLabels({"姓名", "性别", "年龄", "学号", "电话"}); table->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); // 输入学生信息控件 nameEdit = new QLineEdit; genderEdit = new QLineEdit; ageEdit = new QLineEdit; idEdit = new QLineEdit; phoneEdit = new QLineEdit; addBtn = new QPushButton("新增学生"); delBtn = new QPushButton("删除学生"); // 布局 QVBoxLayout *rightLayout = new QVBoxLayout; // 垂直布局 rightLayout->addWidget(new QLabel("姓名")); // index 0 rightLayout->addWidget(nameEdit); // index 1 rightLayout->addWidget(new QLabel("性别")); rightLayout->addWidget(genderEdit); rightLayout->addWidget(new QLabel("年龄")); rightLayout->addWidget(ageEdit); rightLayout->addWidget(new QLabel("学号")); rightLayout->addWidget(idEdit); rightLayout->addWidget(new QLabel("电话")); rightLayout->addWidget(phoneEdit); rightLayout->addWidget(addBtn); rightLayout->addWidget(delBtn); rightLayout->addStretch(); // 设置可伸缩对齐 QHBoxLayout *mainLayout = new QHBoxLayout(central); // 水平布局 mainLayout->addWidget(tree, 1); // index 1 mainLayout->addWidget(table, 3); // index 3 mainLayout->addLayout(rightLayout, 2); // index 2 // 指定信号 槽 // 右键点击弹出增删改班级窗口 connect(tree, &QTreeWidget::customContextMenuRequested, // 右键点击信号 this, &MainWindow::showTreeMenu); // 左键点击班级名 刷新中间的学生信息 connect(tree, &QTreeWidget::itemClicked, // 左键点击信号 this, &MainWindow::onClassClicked); // 左键点击执行添加学生逻辑 connect(addBtn, &QPushButton::clicked, this, &MainWindow::addStudent); // 左键点击执行删除学生逻辑 connect(delBtn, &QPushButton::clicked, this, &MainWindow::deleteStudent); // 点击学生单元格 回显学生信息 connect(table, &QTableWidget::cellClicked, // 单元格点击信号 this, &MainWindow::tableItemClicked); // 确认窗口大小 resize(900, 600); setMinimumSize(800, 500); } void MainWindow::showTreeMenu(const QPoint &pos) { // 右键点击 后触发这个函数 QMenu menu; QAction *add = menu.addAction("新建班级"); QAction *del = menu.addAction("删除班级"); QAction *ren = menu.addAction("重命名班级"); // 显示右键菜单 并获取用户选择 QAction *ret = menu.exec(tree->viewport()->mapToGlobal(pos)); // 执行用户选择的操作 if (ret == add) addClass(); else if (ret == del) deleteClass(); else if (ret == ren) renameClass(); } void MainWindow::addClass() { // 弹出对话框 输入班级名称 QString name = QInputDialog::getText(this, "新建班级", "班级名称"); if (name.isEmpty()) return; // 检查班级是否已存在 if (classData.contains(name)) { QMessageBox::warning(this, "错误", "班级已存在,请重新输入"); return; } // 将新班级添加到数据结构和树控件中 // 由于是新班级,初始化为空列表 classData[name] = {}; // 在树控件中添加新节点 // 数据与UI同步更新 tree->addTopLevelItem(new QTreeWidgetItem({name})); } void MainWindow::deleteClass() { // 获取当前选中班级 // auto == QTreeWidgetItem* auto item = tree->currentItem(); if (!item) return; QString name = item->text(0); // 获取选中项的班级名称 // 弹出确认对话框 if (QMessageBox::question(this, "确认", "确定删除班级?") == QMessageBox::Yes) { // 从数据结构和树控件中删除班级 classData.remove(name); // 数据与UI同步更新 delete item; // 避免内存泄漏 table->clearContents(); // 清理学生信息内容 table->setRowCount(0); // 清空表格行数 } QMessageBox::information(this, "提示", "班级已删除"); } void MainWindow::renameClass() { // 获取当前选中班级 auto item = tree->currentItem(); if (!item) return; // 获取旧班级名称 QString oldName = item->text(0); // 弹出对话框 输入新名称 QString newName = QInputDialog::getText(this, "重命名", "新名称"); // 检查新名称有效性 if (newName.isEmpty()) return; if (classData.contains(newName)) QMessageBox::warning(this, "提示", "班级已存在"); // 更新数据结构和树控件 classData[newName] = classData.take(oldName); // 从数据结构中移除旧键值对,并返回旧名称关联的值,赋给新名称 item->setText(0, newName); } void MainWindow::onClassClicked(QTreeWidgetItem *item) { // 用户点击班级节点后触发此函数 Q_UNUSED(item) // 避免未使用参数警告 refreshTable(); // 刷新右侧学生表格内容 } QString MainWindow::currentClass() const // 只读成员函数 { // 获取当前选中班级名称 auto == QTreeWidgetItem* auto item = tree->currentItem(); return item ? item->text(0) : ""; } void MainWindow::refreshTable() { QString cls = currentClass(); table->setRowCount(0); // 先清空表格内容 if (!classData.contains(cls)) return; // 班级不存在 auto &list = classData[cls]; // 获取当前班级的学生列表引用 table->setRowCount(list.size()); // 设置表格行数为学生数量 for (int i = 0; i < list.size(); ++i) { // 遍历学生列表 填充表格内容 table->setItem(i, 0, new QTableWidgetItem(list[i].name)); table->setItem(i, 1, new QTableWidgetItem(list[i].gender)); table->setItem(i, 2, new QTableWidgetItem(QString::number(list[i].age))); table->setItem(i, 3, new QTableWidgetItem(list[i].id)); table->setItem(i, 4, new QTableWidgetItem(list[i].phone)); } } void MainWindow::addStudent() { QString cls = currentClass(); if (cls.isEmpty()) return; Student s; s.name = nameEdit->text(); s.gender = genderEdit->text(); s.id = idEdit->text(); s.phone = phoneEdit->text(); // 处理年龄:用toInt的第二个参数判断是否为有效数字 bool isAgeValid; // 检测是否转换成功 int age = ageEdit->text().toInt(&isAgeValid); if (!isAgeValid || age <= 0 || age > 120) // 年龄有效条件:转换成功 + 年龄在合理范围 { QMessageBox::warning(this, "错误", "年龄必须是1-120的整数"); return; } s.age = age; // 只有年龄有效,才赋值给结构体 // qDebug() << s.name << s.id << s.age << s.phone << s.gender; if (s.name.isEmpty() || s.gender.isEmpty() || s.id.isEmpty() || s.phone.isEmpty()) { QMessageBox::warning(this, "错误", "信息不完整(姓名、性别、学号、电话不能为空)"); return; } for (auto &st : classData[cls]) { if (st.id == s.id) { QMessageBox::warning(this, "错误", "学号重复"); return; } } classData[cls].append(s); // 将新学生追加到当前班级的学生列表 refreshTable(); // 刷新输入框内容 nameEdit->clear(); genderEdit->clear(); ageEdit->clear(); idEdit->clear(); phoneEdit->clear(); } void MainWindow::deleteStudent() { QString cls = currentClass(); // 拿到班级名称 int row = table->currentRow(); // 获取当前选中行 if (cls.isEmpty() || row < 0) return; if (QMessageBox::question(this, "确认", "删除该学生?") == QMessageBox::Yes) { classData[cls].removeAt(row); refreshTable(); } } void MainWindow::tableItemClicked(int row, int) // 点击学生信息进行回显 { QString cls = currentClass(); if (cls.isEmpty()) return; auto s = classData[cls][row]; nameEdit->setText(s.name); genderEdit->setText(s.gender); ageEdit->setText(QString::number(s.age)); idEdit->setText(s.id); phoneEdit->setText(s.phone); }