目标:旨在开发一个用户友好的软件工具,用于协助用户基于输入对象的成绩数据进行排序。该工具的特色在于,新输入的数据将以红色高亮显示,从而直观地展现出排序过程中数据变化的每一个步骤。
结果展示:
本程序是一个基于Qt框架开发的用户友好型软件工具,专为管理和展示运动员成绩信息而设计。 该程序的亮点在于其直观的数据展示方式。新输入或更新的运动员数据会以红色高亮显示,使用户能够清晰地追踪每次操作后数据的变化。 通过精心设计的GUI,该工具提供了清晰、易于导航的用户界面,包括用于数据展示的表格视图、用于输入和编辑运动员信息的表单,以及一系列操作按钮,如排序、添加新运动员、编辑选定运动员和删除运动员等。整个应用旨在为教练、体育分析师或团队管理者等用户提供一个高效、直观的运动员管理和分析平台。
话不多说直接上代码!
关于如何使用VSCode实现C++编程给大家推荐这个博文,写的很好:vscode配置C/C++环境(超详细保姆级教学)-CSDN博客
1)先定义一个对象,包含姓名、年龄、身高和成绩等属性。
#include
#include
#include
using namespace std;
class Athlete {
public:
string name;
int age;
float height;
float score;
Athlete(string n, int a, float h, float s) : name(n), age(a), height(h), score(s) {}
bool operator < (const Athlete& athlete) const {
return score < athlete.score;
}
};
2)若数据集小用直接插入排序最快,数据集大用快速排序比较好,因此选取了这两种方法,可根据数据集大小自行选择。
// 直接插入排序
void insertionSort(vector& arr) {
for (int i = 1; i < arr.size(); i++) {
Athlete key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j].score > key.score) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}
// 快速排序
int partition(vector& arr, int low, int high) {
float pivot = arr[high].score;
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (arr[j].score < pivot) {
i++;
swap(arr[i], arr[j]);
}
}
swap(arr[i + 1], arr[high]);
return (i + 1);
}
void quickSort(vector& arr, int low, int high) {
if (low < high) {
int pi = partition(arr, low, high);
quickSort(arr, low, pi - 1);
quickSort(arr, pi + 1, high);
}
}
算法相关的内容大概就这些,现在开始使用Qt实现可视化界面。
Qt下载:Index of /archive/qt
关于Qt的学习分享一个up主的课程:1.4 Qt的安装_哔哩哔哩_bilibili
程序结构文件:
#ifndef ATHLETE_H
#define ATHLETE_H
#include
using std::string;
class Athlete {
public:
string name;
float scores[6] = {0}; // 假设有6轮成绩
float totalScore = 0; // 总成绩
// 更新指定轮次的成绩并重新计算总成绩
void updateScore(int round, float score) {
if (round >= 1 && round <= 6) { // 确保轮次有效
scores[round - 1] = score; // 更新成绩,轮次从1开始,数组索引从0开始
calculateTotalScore(); // 重新计算总成绩
}
}
// 计算总成绩
void calculateTotalScore() {
totalScore = 0;
for (int i = 0; i < 6; ++i) {
totalScore += scores[i];
}
}
};
#endif // ATHLETE_H
#ifndef ATHLETEMODEL_H
#define ATHLETEMODEL_H
#include
#include "athlete.h" // 确保这里正确包含了你的Athlete类定义
class AthleteModel : public QStandardItemModel {
Q_OBJECT
public:
explicit AthleteModel(QObject *parent = nullptr);
// 添加或更新运动员的成绩,根据需要创建新运动员
void updateAthleteScore(const std::string& name, int round, float score);
private:
// 辅助函数,根据运动员名字查找对应的行。如果找不到,返回-1
int findRowByName(const std::string& name);
};
#endif // ATHLETEMODEL_H
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include "athlete.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void displayAthleteInfo(const std::vector& athletes);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "athletemodel.h"
#include
#include // 用于设置颜色
AthleteModel::AthleteModel(QObject *parent) : QStandardItemModel(parent) {
setHorizontalHeaderLabels({"Name", "1", "2", "3", "4", "5", "6", "Total"});
}
void AthleteModel::updateAthleteScore(const std::string& name, int round, float score) {
int row = findRowByName(name);
QBrush redBrush(Qt::red);
QBrush defaultBrush(Qt::black); // 默认颜色
int newRow = -1; // 新行索引
// 首先,将所有行的颜色设置回默认颜色
for (int r = 0; r < rowCount(); ++r) {
for (int c = 0; c < columnCount(); ++c) {
auto item = this->item(r, c);
item->setForeground(defaultBrush);
}
}
if (row == -1) {
// 运动员不存在,创建新运动员
QList items;
items << new QStandardItem(QString::fromStdString(name));
for (int i = 1; i <= 6; ++i) {
items << new QStandardItem(QString::number(i == round ? score : 0.0f)); // 除了当前轮次外其他成绩初始化为0
}
items << new QStandardItem(QString::number(score)); // 总成绩初始化为当前轮次成绩
newRow = rowCount(); // 新添加的行是当前行数(因为还没有实际添加)
appendRow(items);
} else {
// 运动员已存在,更新成绩
auto scoreItem = item(row, round);
float oldScore = scoreItem->text().toFloat();
scoreItem->setText(QString::number(score));
// 更新总成绩
auto totalItem = item(row, 7);
float totalScore = totalItem->text().toFloat() - oldScore + score;
totalItem->setText(QString::number(totalScore));
newRow = row; // 更新的行就是找到的行
if (newRow != -1) {
for (int column = 0; column < columnCount(); ++column) {
auto item = this->item(newRow, column);
item->setForeground(redBrush);
}
}
}
}
int AthleteModel::findRowByName(const std::string& name) {
for (int row = 0; row < rowCount(); ++row) {
if (item(row, 0)->text() == QString::fromStdString(name)) {
return row;
}
}
return -1; // 运动员不存在
}
#include "mainwindow.h"
#include "athlete.h"
#include
int main(int argc, char *argv[])
{
// 应用程序类,在一个qt应用程序中,该对象只有一个
QApplication a(argc, argv);
// 窗口对象
MainWindow w;
// 显示函数
w.show();
// 阻塞函数,程序事件循环
return a.exec();
}
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "athletemodel.h"
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
// 设置窗口标题
setWindowTitle("运动员成绩显示系统");
// 设置窗口图标
setWindowIcon(QIcon("E:\\CoachManagementSystem\\shooting coaches and athletes.png"));
auto model = new AthleteModel(this);
auto proxyModel = new QSortFilterProxyModel(this);
proxyModel->setSourceModel(model);
ui->tableView->setModel(proxyModel);
ui->comboBox->addItems({"1", "2", "3", "4", "5", "6"});
connect(ui->pushButton, &QPushButton::clicked, this, [this, model, proxyModel]() {
QString name = ui->textEdit_2->toPlainText().trimmed();
float score = static_cast(ui->doubleSpinBox->value());
int round = ui->comboBox->currentIndex() + 1; // +1 because rounds are 1-based
if (name.isEmpty()) {
// Handle empty name input appropriately
return;
}
// 更新或添加运动员成绩
model->updateAthleteScore(name.toStdString(), round, score); // 此方法需要在model中实现
// 重新排序,这里假设proxyModel已经设置为根据总成绩降序排序
proxyModel->sort(7, Qt::DescendingOrder); // 假设总成绩在第8列(列索引为7)
ui->tableView->reset();
});
}
MainWindow::~MainWindow() {
delete ui;
}
MainWindow
0
0
1061
589
MainWindow
470
500
91
31
更新
350
500
91
31
999.990000000000009
220
480
31
16
姓名
380
480
31
16
成绩
510
20
91
16
实时成绩展示
150
500
171
31
30
500
101
31
15
41
1031
421
0
0
1061
26
C++学习笔记 | 基于Qt框架开发实时成绩显示排序系统2——折线图显示-CSDN博客