C++学习笔记 | 基于Qt框架开发实时成绩显示排序系统1

news2024/10/6 1:37:29

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

结果展示:

        本程序是一个基于Qt框架开发的用户友好型软件工具,专为管理和展示运动员成绩信息而设计。 该程序的亮点在于其直观的数据展示方式。新输入或更新的运动员数据会以红色高亮显示,使用户能够清晰地追踪每次操作后数据的变化。 通过精心设计的GUI,该工具提供了清晰、易于导航的用户界面,包括用于数据展示的表格视图、用于输入和编辑运动员信息的表单,以及一系列操作按钮,如排序、添加新运动员、编辑选定运动员和删除运动员等。整个应用旨在为教练、体育分析师或团队管理者等用户提供一个高效、直观的运动员管理和分析平台。 

        话不多说直接上代码!


一、算法实现 (此步请直接跳过)

关于如何使用VSCode实现C++编程给大家推荐这个博文,写的很好:vscode配置C/C++环境(超详细保姆级教学)-CSDN博客

1)先定义一个对象,包含姓名、年龄、身高和成绩等属性。

#include <iostream>
#include <vector>
#include <algorithm>
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<Athlete>& 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<Athlete>& 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<Athlete>& 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下载:Index of /archive/qt
关于Qt的学习分享一个up主的课程:1.4 Qt的安装_哔哩哔哩_bilibili

程序结构文件:

1)athlete.h
#ifndef ATHLETE_H
#define ATHLETE_H

#include <string>
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 <QStandardItemModel>
#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 <QMainWindow>
#include <vector>
#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<Athlete>& athletes);
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
4)athletemodel.cpp
#include "athletemodel.h"
#include <QStandardItem>
#include <QBrush> // 用于设置颜色

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<QStandardItem*> 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 <QApplication>


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 <QSortFilterProxyModel>


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<float>(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
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1061</width>
    <height>589</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>470</x>
      <y>500</y>
      <width>91</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>更新</string>
    </property>
   </widget>
   <widget class="QDoubleSpinBox" name="doubleSpinBox">
    <property name="geometry">
     <rect>
      <x>350</x>
      <y>500</y>
      <width>91</width>
      <height>31</height>
     </rect>
    </property>
    <property name="maximum">
     <double>999.990000000000009</double>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>220</x>
      <y>480</y>
      <width>31</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>姓名</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>380</x>
      <y>480</y>
      <width>31</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>成绩</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_3">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>20</y>
      <width>91</width>
      <height>16</height>
     </rect>
    </property>
    <property name="text">
     <string>实时成绩展示</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit_2">
    <property name="geometry">
     <rect>
      <x>150</x>
      <y>500</y>
      <width>171</width>
      <height>31</height>
     </rect>
    </property>
   </widget>
   <widget class="QComboBox" name="comboBox">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>500</y>
      <width>101</width>
      <height>31</height>
     </rect>
    </property>
   </widget>
   <widget class="QTableView" name="tableView">
    <property name="geometry">
     <rect>
      <x>15</x>
      <y>41</y>
      <width>1031</width>
      <height>421</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1061</width>
     <height>26</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024刘谦春晚第二个扑克牌魔术

前言 就是刚才看春晚感觉这个很神奇&#xff0c;虽然第一个咱模仿不过来&#xff0c;第二个全国人民这么多人&#xff0c;包括全场观众都有成功&#xff0c;这肯定是不需要什么技术&#xff0c;那我觉得这个肯定就是数学了&#xff0c;于是我就胡乱分析一通。 正文 首先准备…

华为问界M9:领跑未来智能交通的自动驾驶黑科技

华为问界M9是一款高端电动汽车&#xff0c;其自动驾驶技术是该车型的重要卖点之一。华为在问界M9上采用了多种传感器和高级算法&#xff0c;实现了在不同场景下的自动驾驶功能&#xff0c;包括自动泊车、自适应巡航、车道保持、自动变道等。 华为问界M9的自动驾驶技术惊艳之处…

电商小程序04实现登录逻辑

目录 1 创建自定义方法2 获取用户名和密码3 验证用户是否同意协议4 验证用户名和密码总结 上一篇我们实现了登录功能的前端界面&#xff0c;这一篇实现一下登录的具体逻辑。 1 创建自定义方法 一般如果页面点击按钮需要有事件响应的&#xff0c;我们用自定义方法来实现。打开我…

【Linux系统学习】5.Linux实用操作 下

7.虚拟机配置固定IP 7.1 为什么需要固定IP 当前我们虚拟机的Linux操作系统&#xff0c;其IP地址是通过DHCP服务获取的。 DHCP&#xff1a;动态获取IP地址&#xff0c;即每次重启设备后都会获取一次&#xff0c;可能导致IP地址频繁变更 原因1&#xff1a;办公电脑IP地址变化无所…

第77讲用户管理功能实现

用户管理功能实现 前端&#xff1a; views/user/index.vue <template><el-card><el-row :gutter"20" class"header"><el-col :span"7"><el-input placeholder"请输入用户昵称..." clearable v-model"…

FAST角点检测算法

FAST&#xff08;Features from Accelerated Segment Test&#xff09;角点检测算法是一种快速且高效的角点检测方法。它通过检测每个像素周围的连续像素集合&#xff0c;确定是否为角点。以下是 FAST 角点检测算法的基本流程&#xff1a; FAST 角点检测算法的基本过程主要包括…

2024-02-11 Unity 编辑器开发之编辑器拓展2 —— 自定义窗口

文章目录 1 创建窗口类2 显示窗口3 窗口事件回调函数4 窗口中常用的生命周期函数5 编辑器窗口类中的常用成员6 小结 1 创建窗口类 ​ 当想为 Unity 拓展一个自定义窗口时&#xff0c;只需实现继承 EditorWindow 的类即可&#xff0c;并在该类的 OnGUI 函数中编写面板控件相关的…

黄金交易策略(Nerve Nnife.mql4):三档移动止盈机制设计

和中国电费一样&#xff0c;一档档的上。 完整EA&#xff1a;Nerve Knife.ex4黄金交易策略_黄金趋势ea-CSDN博客 mql4代码节选如下&#xff1a; //第一张单上涨2500&#xff0c;开始SL跟踪300点if (count 1 && !follow_p_3){double ctp calcTotalProfit(0, "b…

JavaScript中的for循环和map方法

JavaScript中的for循环和map方法 在JavaScript中&#xff0c;循环是一种常见的编程技巧&#xff0c;用于重复执行一段代码。for循环和map方法都可以用于循环操作&#xff0c;但它们在语法和应用场景上存在一些区别。本文将详细讲解JavaScript中的for循环和map方法&#xff0c;以…

springboot178智能学习平台系统

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

精品springboot校园资产管理-出入库维修报废

《[含文档PPT源码等]精品基于springboot校园资产管理[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&#xff1a;HTML5,CSS3…

《UE5_C++多人TPS完整教程》学习笔记2 ——《P3 多人游戏概念(Multiplayer Concept)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P3 多人游戏概念&#xff08;Multiplayer Concept&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译…

人工智能(pytorch)搭建模型24-SKAttention注意力机制模型的搭建与应用场景

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能(pytorch)搭建模型24-SKAttention注意力机制模型的搭建与应用场景&#xff0c;本文将介绍关于SKAttention注意力机制模型的搭建&#xff0c;SKAttention机制具有灵活性和通用性&#xff0c;可应用于计算机视…

电视上如何下载软件

电视上如何下载软件&#xff0c;告诉大家一个简单的方法&#xff0c;可以用DT浏览器下载软件&#xff0c;然后会自动安装这个软件&#xff0c;如有技术问题&#xff0c;可以免费解答

4、解构三个重要的Pipeline(SD-Inpainting, ControlNet, AnimateDiff) [代码级手把手解析diffusers库]

上一篇我们解析了所有Pipeline的基类DiffusionPipeline。后续各种各样的pipeline都继承了DiffusionPipeline的模型加载保存等功能,然后再配合各个组件实现各种的结构即可。 事实上,一个Pipeline通常包含了如下模块(from_pretrained函数根据model_index.json文件new了一个Pipe…

disql备份还原

disql备份还原 前言 本文档根据官方文档&#xff0c;进行整理。 一、概述 在 disql 工具中使用 BACKUP 语句你可以备份整个数据库。通常情况下&#xff0c;在数据库实例配置归档后输入以下语句即可备份数据库&#xff1a; BACKUP DATABASE BACKUPSET db_bak_01;语句执行完…

spring boot(2.4.x 开始)和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 spring boot 2.4.x 版本之前通过 ConfigFileApplicationListener 加载配置 https://github.com/spring-projects/spring-boot/blob/v2.3.12.RELEASE/spring-boot-project/spring-boot/src/mai…

使用耳机壳UV树脂制作私模定制耳塞有哪些选择呢?

私模定制耳塞人士的选择可以从以下几个方面考虑&#xff1a; 专业经验&#xff1a;选择有丰富经验的私模定制耳塞人士&#xff0c;能够更好地理解用户需求&#xff0c;提供更专业的建议和服务。可以通过查看其作品和客户评价来了解其经验和口碑。材料质量&#xff1a;选择使用…

第五篇:MySQL常见数据类型

MySQL中的数据类型有很多&#xff0c;主要分为三类:数值类型、字符串类型、日期时间类型 三个表格都在此网盘中&#xff0c;需要者可移步自取&#xff0c;如果觉得有帮助希望点个赞~ MySQL常见数据类型表 数值类型 &#xff08;注&#xff1a;decimal类型举例&#xff0c;如1…

【闲谈】开源软件的崛起与影响

随着信息技术的快速发展&#xff0c;开源软件已经成为软件开发的趋势&#xff0c;并产生了深远的影响。开源软件的低成本、可协作性和透明度等特点&#xff0c;使得越来越多的企业和个人选择使用开源软件&#xff0c;促进了软件行业的繁荣。然而&#xff0c;在使用开源软件的过…