C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(1)

目标:旨在开发一个用户友好的软件工具,用于协助用户基于输入对象的成绩数据进行排序。该工具的特色在于,新输入的数据将以红色高亮显示,从而直观地展现出排序过程中数据变化的每一个步骤。

结果展示:

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(1)_第1张图片

        本程序是一个基于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 实现(我使用的是Qt 5.14.2)

Qt下载:Index of /archive/qt
关于Qt的学习分享一个up主的课程:1.4 Qt的安装_哔哩哔哩_bilibili

程序结构文件:

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(1)_第2张图片

1)athlete.h
#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
2)athletemodel.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
3)mainwindow.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
4)athletemodel.cpp
#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; // 运动员不存在
}
5)main.cpp
#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();
}
6)mainwindow.cpp
//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;
}
7)mainwindow.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博客

你可能感兴趣的:(Qt,开发,c++,qt,笔记,开发语言,学习,开源软件)