使用pyqt5制作简单计分桌面应用

pyqt5 · 浏览次数 : 96

小编点评

本文介绍了一个使用Python和PyQt5制作的简单计分桌面应用程序。该程序主要用于艺术类比赛的评分统计,旨在帮助参赛者更方便地统计和展示比赛分数。 1. **项目背景**: - 艺术类比赛中,需要对选手的成绩进行统计和展示。 - 使用PyQt5库创建了一个简单的计分桌面应用程序。 2. **UI设计与实现**: - 使用Qt Designer设计了应用程序的用户界面(UI)。 - 实现了界面的布局和交互逻辑。 - 设计了多个组件,如表格、标签、按钮等。 3. **核心功能**: - 文件上传与读取:从本地文件夹读取文件,解析其中的数据。 - 分数计算:根据上传的文件计算选手的得分。 - 计算总分:将选手的得分汇总并展示。 - 保存信息:将计算结果保存到Excel文件中。 4. **程序结构**: - 包含了主窗口(MyWindow)类,负责管理应用程序的核心逻辑。 - 包含了数据模型(DataFrame)类,用于存储和操作数据。 - 包含了文件处理相关的小模块。 5. **运行与打包**: - 使用PyInstaller将Python脚本转换为可执行文件(exe)。 - 设置了程序的安装目录路径。 总的来说,本文通过展示一个简单的计分应用程序的开发过程,向读者展示了如何使用PyQt5和Python来创建一个功能丰富的桌面应用。

正文

这是一个自己写的使用pyqt5制作简单计分桌面应用的实例,希望对大家有所帮助。制作这个小程序的起因是因为有个艺术类比赛需要设计这个一个桌面程序,方便统分。

(此程序尚存在部分小bug,请慎用,公开代码只为让小白熟悉如何开发一个简单的桌面计分程序)

ui设计

众所周知,使用pyqt5开发可以直接使用designer来设计界面,所以,我将页面代码直接贴给大家,具体效果截图展示。

比赛准备阶段界面

image-20240711143434332

比赛进行中界面

image-20240711143507616

完整ui代码

为了方便,并没有转成.py形式的文件

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="enabled">
   <bool>true</bool>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1920</width>
    <height>1080</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>1920</width>
    <height>1080</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>1920</width>
    <height>1080</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <widget class="QWidget" name="race_prepare_page" native="true">
   <property name="enabled">
    <bool>true</bool>
   </property>
   <property name="geometry">
    <rect>
     <x>440</x>
     <y>130</y>
     <width>1211</width>
     <height>721</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true"/>
   </property>
   <widget class="QTableWidget" name="score_table_display">
    <property name="enabled">
     <bool>true</bool>
    </property>
    <property name="geometry">
     <rect>
      <x>580</x>
      <y>190</y>
      <width>621</width>
      <height>341</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
   </widget>
   <widget class="QLabel" name="score_display_label">
    <property name="geometry">
     <rect>
      <x>830</x>
      <y>540</y>
      <width>131</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>选手信息展示</string>
    </property>
   </widget>
   <widget class="QPushButton" name="race_info_button">
    <property name="geometry">
     <rect>
      <x>200</x>
      <y>660</y>
      <width>121</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>确认信息</string>
    </property>
   </widget>
   <widget class="QPushButton" name="race_start_button">
    <property name="geometry">
     <rect>
      <x>740</x>
      <y>90</y>
      <width>121</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>比赛开始</string>
    </property>
   </widget>
   <widget class="QLabel" name="race_preparation_label">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>10</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 30px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>比赛准备阶段</string>
    </property>
   </widget>
   <widget class="QLabel" name="music_name_label">
    <property name="enabled">
     <bool>true</bool>
    </property>
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>350</y>
      <width>91</width>
      <height>81</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>请按选手排序输入曲名名称</string>
    </property>
    <property name="wordWrap">
     <bool>true</bool>
    </property>
   </widget>
   <widget class="QRadioButton" name="remove_yes">
    <property name="geometry">
     <rect>
      <x>250</x>
      <y>560</y>
      <width>61</width>
      <height>21</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>是</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judge_number_input">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>110</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="race_name_label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>60</y>
      <width>91</width>
      <height>24</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>比赛名称</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="judge_namelist_input">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>160</y>
      <width>151</width>
      <height>171</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="markdown">
     <string/>
    </property>
    <property name="html">
     <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'SimSun'; font-size:20px; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
    <property name="placeholderText">
     <string>填写示例:   张三                 李四</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_number_label">
    <property name="geometry">
     <rect>
      <x>11</x>
      <y>116</y>
      <width>81</width>
      <height>24</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>评委数量</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="player_namelist_input">
    <property name="geometry">
     <rect>
      <x>390</x>
      <y>160</y>
      <width>151</width>
      <height>171</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="markdown">
     <string/>
    </property>
    <property name="html">
     <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'SimSun'; font-size:20px; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
    <property name="placeholderText">
     <string>填写示例:   张三               李四</string>
    </property>
   </widget>
   <widget class="QLabel" name="player_name_label">
    <property name="geometry">
     <rect>
      <x>300</x>
      <y>160</y>
      <width>91</width>
      <height>81</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>请按选手排序输入姓名</string>
    </property>
    <property name="wordWrap">
     <bool>true</bool>
    </property>
   </widget>
   <widget class="QLineEdit" name="race_name_input">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>54</y>
      <width>441</width>
      <height>31</height>
     </rect>
    </property>
    <property name="accessibleName">
     <string/>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="inputMask">
     <string/>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>默认比赛</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_name_label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>160</y>
      <width>91</width>
      <height>81</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>请按评委排序输入姓名</string>
    </property>
    <property name="wordWrap">
     <bool>true</bool>
    </property>
   </widget>
   <widget class="QLineEdit" name="player_number_input">
    <property name="geometry">
     <rect>
      <x>390</x>
      <y>110</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QRadioButton" name="remove_no">
    <property name="geometry">
     <rect>
      <x>340</x>
      <y>560</y>
      <width>51</width>
      <height>21</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>否</string>
    </property>
   </widget>
   <widget class="QLabel" name="remove_score_label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>614</y>
      <width>221</width>
      <height>24</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>去掉几个最高分和最低分</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="remove_score_input">
    <property name="geometry">
     <rect>
      <x>250</x>
      <y>610</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="player_number_label">
    <property name="geometry">
     <rect>
      <x>300</x>
      <y>116</y>
      <width>91</width>
      <height>24</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>选手数量</string>
    </property>
   </widget>
   <widget class="QLabel" name="remove_choose_label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>560</y>
      <width>221</width>
      <height>24</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>是否去掉最高分和最低分</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="music_namelist_input">
    <property name="geometry">
     <rect>
      <x>100</x>
      <y>350</y>
      <width>441</width>
      <height>181</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="markdown">
     <string/>
    </property>
    <property name="html">
     <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'SimSun'; font-size:20px; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
    </property>
    <property name="placeholderText">
     <string>填写示例:                                  古典乐                                       爵士乐</string>
    </property>
   </widget>
   <widget class="QPushButton" name="continue_race_button">
    <property name="geometry">
     <rect>
      <x>890</x>
      <y>90</y>
      <width>151</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>继续上次比赛</string>
    </property>
   </widget>
   <widget class="QPushButton" name="quit_code_button">
    <property name="geometry">
     <rect>
      <x>1070</x>
      <y>90</y>
      <width>121</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>退出程序</string>
    </property>
   </widget>
   <widget class="QPushButton" name="save_info_button">
    <property name="geometry">
     <rect>
      <x>590</x>
      <y>90</y>
      <width>121</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>保存信息</string>
    </property>
   </widget>
  </widget>
  <widget class="QWidget" name="race_going_page" native="true">
   <property name="geometry">
    <rect>
     <x>440</x>
     <y>130</y>
     <width>1211</width>
     <height>721</height>
    </rect>
   </property>
   <widget class="QLabel" name="race_going_label">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>10</y>
      <width>1211</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 30px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>比赛进行阶段</string>
    </property>
    <property name="alignment">
     <set>Qt::AlignCenter</set>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_1">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>146</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:1号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_1">
    <property name="geometry">
     <rect>
      <x>300</x>
      <y>150</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_2">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>202</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:2号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_2">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>206</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_3">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>252</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:3号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_3">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>256</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_4">
    <property name="geometry">
     <rect>
      <x>300</x>
      <y>310</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_4">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>306</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:4号评委</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_5">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>362</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:5号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_5">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>366</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_6">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>422</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:6号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_6">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>426</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_7">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>482</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:7号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_7">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>486</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_8">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>542</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:8号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_8">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>546</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_one_label_9">
    <property name="geometry">
     <rect>
      <x>81</x>
      <y>602</y>
      <width>181</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px;</string>
    </property>
    <property name="text">
     <string>姓名:9号评委</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="judgeone_score_input_9">
    <property name="geometry">
     <rect>
      <x>301</x>
      <y>606</y>
      <width>151</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px ;</string>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="placeholderText">
     <string>填写示例:1</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_com_label_1">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>250</y>
      <width>151</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 24px;</string>
    </property>
    <property name="text">
     <string>最高分:</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_com_label_2">
    <property name="geometry">
     <rect>
      <x>700</x>
      <y>250</y>
      <width>161</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 24px;</string>
    </property>
    <property name="text">
     <string>最低分:</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_com_label_3">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>320</y>
      <width>151</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 30px;</string>
    </property>
    <property name="text">
     <string>实际得分:</string>
    </property>
   </widget>
   <widget class="QLabel" name="judge_com_label_4">
    <property name="geometry">
     <rect>
      <x>670</x>
      <y>300</y>
      <width>181</width>
      <height>81</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 60px;</string>
    </property>
    <property name="text">
     <string/>
    </property>
   </widget>
   <widget class="QPushButton" name="next_player_button">
    <property name="geometry">
     <rect>
      <x>630</x>
      <y>170</y>
      <width>151</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>下一个选手</string>
    </property>
   </widget>
   <widget class="QPushButton" name="exit_race_button">
    <property name="geometry">
     <rect>
      <x>970</x>
      <y>170</y>
      <width>151</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>比赛结束</string>
    </property>
   </widget>
   <widget class="QLabel" name="current_player_label">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>90</y>
      <width>1091</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 24px;</string>
    </property>
    <property name="text">
     <string>当前选手:</string>
    </property>
   </widget>
   <widget class="QPushButton" name="player_quit_button">
    <property name="geometry">
     <rect>
      <x>800</x>
      <y>170</y>
      <width>151</width>
      <height>51</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 20px &quot;Adobe Arabic&quot;;</string>
    </property>
    <property name="text">
     <string>当前选手弃权</string>
    </property>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

代码设计

程序主要功能包含,文件上传,文件读取,分数计算,然后还有一些按钮绑定事件。

from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5 import uic

import keyboard
import sys
import os
import pandas as pd
import docx

def get_path(relative_path):
    try:
        base_path = sys._MEIPASS
    except AttributeError:
        base_path = os.path.abspath(".")

    return os.path.normpath(os.path.join(base_path, relative_path))

def get_decimal_places(num):
    import decimal
    if '.' in str(num):
        num = str(float(num))   #如果传入的是字符串形式的浮点数,先去掉小数后面无意义的0
    d = decimal.Decimal(str(num))
    return abs(d.as_tuple().exponent)

def del_files(path_file):
    ls = os.listdir(path_file)
    for i in ls:
        f_path = os.path.join(path_file, i)
        # 判断是否是一个目录,若是,则递归删除
        if os.path.isdir(f_path):
            del_files(f_path)
        else:
            os.remove(f_path)


class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = uic.loadUi(get_path("assets/comscore_final.ui")) #读取ui文件
        # 展示窗口
        self.ui.setWindowTitle('比赛计分系统')

        self.ui.setWindowFlag(Qt.WindowCloseButtonHint, False)
        
        #提取每个要使用的控件 
        #比赛准备阶段  
        self.race_prepare=self.ui.race_prepare_page #比赛准备页面

        self.race_name=self.ui.race_name_input #比赛名称

        self.judge_number=self.ui.judge_number_input #评委数量
        self.judge_namelist=self.ui.judge_namelist_input #评委信息

        self.player_number=self.ui.player_number_input #选手数量
        self.player_namelist=self.ui.player_namelist_input #选手信息

        self.music_namelist=self.ui.music_namelist_input #音乐信息

        self.race_info=self.ui.race_info_button #确认信息按钮

        self.continue_race=self.ui.continue_race_button #继续上次比赛按钮
        self.race_start=self.ui.race_start_button #比赛开始按钮'
        self.remove_score=self.ui.remove_score_input 
        self.save_info=self.ui.save_info_button #保存信息
        self.quit_code=self.ui.quit_code_button #退出程序

        self.race_start.setEnabled(False)
        self.save_info.setEnabled(False)

        #是否去掉最高分和最低分
        self.remove_yes_radiobox=self.ui.remove_yes
        self.remove_no_radiobox=self.ui.remove_no

        #去掉最高分和最低分的数量
        self.remove_score_label_now=self.ui.remove_score_label
        self.remove_score=self.ui.remove_score_input 

        #默认选择不去掉,并且设置不显示去掉几个最高分和最低分的框
        self.remove_no_radiobox.setChecked(True)
        self.remove_score.setVisible(False) #初始设置隐藏
        self.remove_score_label_now.setVisible(False) #初始设置隐藏

        #toggled信号与槽函数绑定
        self.remove_yes_radiobox.toggled.connect(lambda :self.func_radiobox_btnstate(self.remove_yes_radiobox))
        self.remove_no_radiobox.toggled.connect(lambda :self.func_radiobox_btnstate(self.remove_no_radiobox))

        #选手信息展示
        self.score_table=self.ui.score_table_display #选手信息展示

        # 绑定信号与槽函数
        self.race_info.clicked.connect(self.func_race_info) #信息导入
        self.continue_race.clicked.connect(self.func_continue_race)# 根据文件来读取信息
        self.race_start.clicked.connect(self.func_race_start) #比赛开始按钮
        self.save_info.clicked.connect(self.func_save_info) #保存信息
        self.quit_code.clicked.connect(self.func_quit_code)


        #选手信息展示区域函数
        self.score_table.setSelectionMode(QAbstractItemView.SingleSelection)#设置选取方式为单个选取
        self.score_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) #设置水平滚动
        self.score_table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)  #设置竖直滚动

        #---------------------------------------------------------------------------------------------------------------------
        #---------------------------------------------------------------------------------------------------------------------

        #比赛进行阶段
        self.race_going=self.ui.race_going_page #比赛进行页面
        self.race_going.setVisible(False) #初始设置隐藏

        self.race_going_name=self.ui.race_going_label

        #当前选手
        self.current_player=self.ui.current_player_label 

        #评委列表
        self.judge_one_1=self.ui.judge_one_label_1
        self.judgeone_score_1=self.ui.judgeone_score_input_1

        #设置校验规则,实例化浮点校验器,并设置范围0~10,精度为小数点两位
        myValidator = QRegExpValidator(QRegExp("^(10|\d(\.\d{1,2})?)$"))

        #初始设置隐藏
        for show_i in range(1,10):
            judge_one_label_name="judge_one_label_"+str(show_i)
            judge_one_temp = self.race_going.findChild(QLabel,judge_one_label_name)
            judge_one_temp.setVisible(False)

            judgeone_score_input_name="judgeone_score_input_"+str(show_i)
            judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
            judgeone_score_temp.setVisible(False)
            #设置校验规则,限制只能输入数字还有小数后两位
            judgeone_score_temp.returnPressed.connect(self.func_text_change)
            judgeone_score_temp.setValidator(myValidator)
        
        #最高分,最低分,实际得分
        self.judge_com_max=self.ui.judge_com_label_1  #最高分
        self.judge_com_min=self.ui.judge_com_label_2  #最低分
        self.judge_com_average_label=self.ui.judge_com_label_3  #实际得分标签
        self.judge_com_average=self.ui.judge_com_label_4 #分数
        for show_i in range(1,5):
            judge_com_label_name="judge_com_label_"+str(show_i)
            judge_com_temp = self.race_going.findChild(QLabel,judge_com_label_name)
            judge_com_temp.setVisible(False)

        #计算总分按钮
        # self.com_score=self.ui.com_score_button 

        #下一个选手按钮
        self.next_player=self.ui.next_player_button 

        #比赛结束按钮
        self.exit_race=self.ui.exit_race_button 

        #选手弃权按钮
        self.player_quit=self.ui.player_quit_button


        # 绑定信号与槽函数
        # self.com_score.clicked.connect(self.func_com_score) #计算总分
        self.next_player.clicked.connect(self.func_next_player) #下一个选手
        self.exit_race.clicked.connect(self.func_exit_race) #结束比赛
        self.player_quit.clicked.connect(self.func_player_quit) #选手弃权
        
        #赋予一个全局使用的数据变量
        self.all_data_df=[]
        self.have_score_number=0 #表示当前已经计分的选手数量
        self.remove_score_number=0

    def func_save_info(self):
        reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否保存信息?',QMessageBox.Question)
        if reply_one == QMessageBox.Yes: 
            #先将读取的数据保存起来,以tablewight数据表信息为准
            player_index=[]
            player_name=[]
            music_name=[]
            for qtable_row in range(int(self.player_number.text())):
                player_index.append(self.score_table.item(qtable_row,0).text())  #获取某行某列item中的x信息
                player_name.append(self.score_table.item(qtable_row,1).text())  #获取某行某列item中的x信息
                music_name.append(self.score_table.item(qtable_row,2).text())  #获取某行某列item中的x信息
            
            judge_all_list=[]
            for qtable_column in range(int(self.judge_number.text())):
                judge_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
                judge_all_list.append(judge_one_list)

            # creating the DataFrame
            all_data = pd.DataFrame(list(zip(player_index, player_name, music_name))) 

            all_data.columns =['抽签序号', '选手姓名', '曲目名称'] #设置列名

            judge_namelist_temp=self.judge_namelist.toPlainText().split('\n')
            for qtable_column in range(int(self.judge_number.text())):
                judge_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
                judge_column_name=judge_namelist_temp[qtable_column]+":"+str(qtable_column+1)+"号评委"
                all_data[judge_column_name]=judge_one_list

            #增加最高分,最低分列 ,增加实际得分列
            if self.remove_yes_radiobox.isChecked()==True:
                max_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['最高分']=max_one_list

                min_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['最低分']=min_one_list

                visual_one_list=[-1]*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['实得分']=visual_one_list

                index_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['最终排名']=index_one_list

                remove_score_str=self.remove_score.text()
                self.remove_score_number=int(self.remove_score.text())
                remove_one_list=[remove_score_str]*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['去掉几个最高分']=remove_one_list
            else:
                visual_one_list=[-1]*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['实得分']=visual_one_list

                index_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['最终排名']=index_one_list

                remove_one_list=['0']*int(self.player_number.text()) #将列数据全部填充为空格
                all_data['去掉几个最高分']=remove_one_list

            all_data['抽签序号']=all_data['抽签序号'].astype(int)
            all_data=all_data.sort_values(by=['抽签序号']) #按照抽签序号排序
            all_data=all_data.reset_index(drop=True) #重新排列一下索引

            all_data.to_excel('temp_data/'+str(self.race_name.text())+'_临时存储数据.xlsx', sheet_name='部分信息', index=True) # index false为不写入索引
            
            #恢复所有数据初始状态
            self.all_data_df=[]
            self.have_score_number=0 #表示当前已经计分的选手数量
            self.remove_score_number=0

            #默认选择不去掉,并且设置不显示去掉几个最高分和最低分的框
            self.remove_no_radiobox.setChecked(True)
            self.remove_score.setVisible(False) #初始设置隐藏
            self.remove_score_label_now.setVisible(False) #初始设置隐藏

            #然后要清空所有的输入
            self.race_name.setText("") #比赛名称

            self.judge_number.setText("") #评委数量
            self.judge_namelist.setText("") #评委信息

            self.player_number.setText("") #选手数量
            self.player_namelist.setText("") #选手信息

            self.music_namelist.setText("") #音乐信息

            #然后清空qtablewight
            self.score_table.setRowCount(0)
            self.score_table.setColumnCount(0)
            self.score_table.clearContents()

            #设置按钮不可用
            self.race_start.setEnabled(False)
            self.save_info.setEnabled(False)

            self.setQMessageBoxoneButtonTextENToCN("提示","保存信息成功",QMessageBox.Information)
            return
        else:
            self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
            return
        return

        return


    def func_quit_code(self):
        reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否退出程序?',QMessageBox.Question)
        if reply_one == QMessageBox.Yes: 
            self.setQMessageBoxoneButtonTextENToCN("提示","退出程序成功",QMessageBox.Information)
            sys.exit(0)
            return
        else:
            self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
            return
        return

    def func_text_change(self):
        #在输入框内按下enter,就会进入这里
        #获取数据,保存这个选手的得分到临时表格中
        all_data_temp=self.all_data_df

        judge_number=0
        if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
            judge_number=int(all_data_temp.shape[1])-8
        else:
            judge_number=int(all_data_temp.shape[1])-6

        #遍历所有输入框,然后找到第一个为空的输入框,设置它为setFocus即可
        for com_i in range(1,judge_number+1):
            judgeone_score_input_name="judgeone_score_input_"+str(com_i)
            judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
            if judgeone_score_temp.text()=='':
                judgeone_score_temp.setFocus()
                return
            else:
                continue

        #获取数据,保存这个选手的得分到临时表格中
        all_data_temp=self.all_data_df
        print(self.all_data_df)
        reply_zero=self.setQMessageBoxtwoButtonTextENToCN('提示', '评委得分是否输入正确?',QMessageBox.Question)
        if reply_zero == QMessageBox.Yes:
            #根据评委数量来获取输入框数据
            score_list_temp=[]
            save_score_list=[]
            judge_number=0
            if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                judge_number=int(all_data_temp.shape[1])-8
            else:
                judge_number=int(all_data_temp.shape[1])-6

            print(judge_number)
            for com_i in range(1,judge_number+1):
                judgeone_score_input_name="judgeone_score_input_"+str(com_i)
                judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)

                judgeone_score_temp.setReadOnly(True)  #设置为只读
                
                if judgeone_score_temp.text()=='':
                    self.setQMessageBoxoneButtonTextENToCN("提示",str(com_i)+"评委分数未填写",QMessageBox.Information)
                    return
                else:
                    score_list_temp.append(float(judgeone_score_temp.text()))
                    save_score_list.append(float(judgeone_score_temp.text()))
            
            print(score_list_temp)
            score_list_temp.sort() #对打分进行排序
            
            #设置最高分
            score_list_temp_max=max(score_list_temp)
            self.judge_com_max.setText("最高分: "+str(score_list_temp_max))
            # self.score_table.setText(score_list_temp_max)

            #设置最低分
            score_list_temp_min=min(score_list_temp)
            self.judge_com_min.setText("最低分: "+str(score_list_temp_min))

            for flag in range(self.remove_score_number):
                score_list_temp.pop() #删除最后一项
                score_list_temp.pop(0) #删除第一项

            #设置最终分数
            average_score=round(sum(score_list_temp)/len(score_list_temp),3)
            #设置
            self.judge_com_average.setText(str(average_score))

            #确定当前计算的是哪个选手,至少有一个评委
            current_player_row=0
            player_row=int(all_data_temp.shape[0])
            for player_row_index in range(0,player_row):
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3]))
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1')
                if str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1' or str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1.0':
                    current_player_row=player_row_index
                    break
                current_player_row=player_row_index
            
            self.have_score_number=current_player_row
            #保存方法在有最高分和没有最高分时有所不同,有
            if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
            #将这里面的数据进行覆盖  操作的是save_score_list,score_list_temp_max,score_list_temp_min
                print(save_score_list)
                for judge_number_index in range(0,judge_number):
                    print(judge_number_index)
                    all_data_temp.iloc[current_player_row,judge_number_index+3]=save_score_list[judge_number_index]   
                
                all_data_temp.iloc[current_player_row,judge_number_index+4]=score_list_temp_max 
                all_data_temp.iloc[current_player_row,judge_number_index+5]=score_list_temp_min
                all_data_temp.iloc[current_player_row,judge_number_index+6]=average_score
            else:
                for judge_number_index in range(0,judge_number):
                    all_data_temp.iloc[current_player_row,judge_number_index+3]=save_score_list[judge_number_index]   
                
                all_data_temp.iloc[current_player_row,judge_number_index+4]=average_score

            #重新保存数据表,最后再赋值回去
            all_data_temp.to_excel('temp_data/'+str(self.race_name.text())+'_临时存储数据.xlsx', sheet_name='部分信息', index=True) # index false为不写入索引

            self.all_data_df=all_data_temp
            print(self.all_data_df)

            # #清空分数框         
            # for show_i in range(1,judge_number+1):
            #     judgeone_score_input_name="judgeone_score_input_"+str(show_i)
            #     judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
            #     judgeone_score_temp.clear()
            
            self.have_score_number=self.have_score_number+1 #保存当前选手序号,只用于验证选手是否弃权
            print("self.have_score_number=",self.have_score_number)

            return
        else:
            self.setQMessageBoxoneButtonTextENToCN("提示","请检查后,继续填写",QMessageBox.Information)
            return


        return


    #单选按钮绑定
    def func_radiobox_btnstate(self,btn):
        #输出按钮1与按钮2的状态,选中还是没选中
        if btn.text()=='是':
            if btn.isChecked()==True:
                # print(btn.text()+"is selected")
                self.remove_score.setVisible(True) #初始设置隐藏
                self.remove_score_label_now.setVisible(True) #初始设置隐藏
            else:
                # print(btn.text()+"is deselected")
                return

        if btn.text()=="否":
            if btn.isChecked() == True:
                # print(btn.text() + "is selected")
                self.remove_score.setVisible(False) #初始设置隐藏
                self.remove_score_label_now.setVisible(False) #初始设置隐藏
                self.remove_score.setText("") #重新设置为空
            else:
                # print(btn.text() + "is deselected")
                return
    def setQMessageBoxtwoButtonTextENToCN(self,windowTitle, text,  qmessageIcon):
        """
        设置需要的QMessageBox的按钮提示为中文
        :param qmessageIcon: 显示图标  例如QMessageBox.Question
        :param kwargs: 确定=QMessageBox.AcceptRole
        """
        msgBox = QMessageBox()
        msgBox.setWindowTitle(windowTitle)
        msgBox.setText(text)
        msgBox.setIcon(qmessageIcon)
        msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        buttonY = msgBox.button(QMessageBox.Yes)
        buttonY.setText('是')
        buttonN = msgBox.button(QMessageBox.No)
        buttonN.setText('否')
        ret=msgBox.exec_()
        return ret
    
    def setQMessageappENToCN(self,windowTitle, text,  qmessageIcon):
        """
        设置需要的QMessageBox的按钮提示为中文
        :param qmessageIcon: 显示图标  例如QMessageBox.Question
        :param kwargs: 确定=QMessageBox.AcceptRole
        """
        msgBox = QMessageBox()
        msgBox.setWindowTitle(windowTitle)
        msgBox.setText(text)
        msgBox.setIcon(qmessageIcon)
        msgBox.setStandardButtons(QMessageBox.Yes | QMessageBox.No)
        buttonY = msgBox.button(QMessageBox.Yes)
        buttonY.setText('比赛暂停')
        buttonN = msgBox.button(QMessageBox.No)
        buttonN.setText('比赛结束')
        ret=msgBox.exec_()
        return ret


    def setQMessageBoxoneButtonTextENToCN(self,windowTitle, text,  qmessageIcon):
        """
        设置需要的QMessageBox的按钮提示为中文
        :param qmessageIcon: 显示图标  例如QMessageBox.Question
        :param kwargs: 确定=QMessageBox.AcceptRole
        """
        msgBox = QMessageBox()
        msgBox.setWindowTitle(windowTitle)
        msgBox.setText(text)
        msgBox.setIcon(qmessageIcon)
        msgBox.setStandardButtons(QMessageBox.Yes)
        buttonY = msgBox.button(QMessageBox.Yes)
        buttonY.setText('是')
        msgBox.exec_()

    #根据输入框来读取信息已经无误
    def func_race_info(self):
        reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否确认比赛准备信息无误?',QMessageBox.Question)

        if reply_one == QMessageBox.No:    
            self.setQMessageBoxoneButtonTextENToCN("提示","请继续填写",QMessageBox.Information)
            return

        #检查是否有未填写数据
        if self.race_name.text()=='' or self.judge_number.text()=='' or self.judge_namelist.toPlainText()=='' or self.player_number.text()==''  or self.player_namelist.toPlainText()=='' or self.music_namelist.toPlainText()=='':
            self.setQMessageBoxoneButtonTextENToCN("提示","有未填写数据",QMessageBox.Information)
            return
        
        if self.remove_score.text()=='' and self.remove_yes_radiobox.isChecked()==True:
            self.setQMessageBoxoneButtonTextENToCN("提示","有未填写数据",QMessageBox.Information)
            return
        #检查评委数量是否足够
        if  int(self.judge_number.text())!=len(self.judge_namelist.toPlainText().split('\n')):
            self.setQMessageBoxoneButtonTextENToCN("提示","评委数量与评委姓名数量不对应,请重新填写",QMessageBox.Information)
            return
        
        #检查选手数量是否足够
        if  int(self.player_number.text())!=len(self.player_namelist.toPlainText().split('\n')):
            self.setQMessageBoxoneButtonTextENToCN("提示","选手数量与选手姓名数量不对应,请重新填写",QMessageBox.Information)
            return
        
        #检查曲目数量是否足够
        if  int(self.player_number.text())!=len(self.music_namelist.toPlainText().split('\n')):
            self.setQMessageBoxoneButtonTextENToCN("提示","音乐数量与选手数量不对应,请重新填写",QMessageBox.Information)
            return

        if reply_one == QMessageBox.Yes:    
            self.setQMessageBoxoneButtonTextENToCN("提示","比赛准备信息填写成功",QMessageBox.Information)          
            self.score_table.setColumnCount(3)
            self.score_table.setRowCount(int(self.player_number.text()))
            column_namelist_temp=["抽签序号","选手姓名","曲目名称"]
            self.score_table.setHorizontalHeaderLabels(column_namelist_temp) #设置行表头

            player_namelist_temp=self.player_namelist.toPlainText().split('\n')
            music_namelist_temp=self.music_namelist.toPlainText().split('\n')
            for i in range(int(self.player_number.text())):
                self.score_table.setItem(i,0, QTableWidgetItem(str(i+1)))
                self.score_table.setItem(i,1, QTableWidgetItem(player_namelist_temp[i]))
                self.score_table.setItem(i,2, QTableWidgetItem(music_namelist_temp[i]))

            #设置按钮可用
            self.race_start.setEnabled(True)
            self.save_info.setEnabled(True)

            #给设置自适应宽度
            self.score_table.resizeColumnToContents(0)
            self.score_table.resizeColumnToContents(1)
            self.score_table.resizeColumnToContents(2)
            return
        return

    #这是按照全新比赛的操作
    def func_race_start(self):
        #先将读取的数据保存起来,以tablewight数据表信息为准
        player_index=[]
        player_name=[]
        music_name=[]
        for qtable_row in range(int(self.player_number.text())):
            player_index.append(self.score_table.item(qtable_row,0).text())  #获取某行某列item中的x信息
            player_name.append(self.score_table.item(qtable_row,1).text())  #获取某行某列item中的x信息
            music_name.append(self.score_table.item(qtable_row,2).text())  #获取某行某列item中的x信息
        
        judge_all_list=[]
        for qtable_column in range(int(self.judge_number.text())):
            judge_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
            judge_all_list.append(judge_one_list)

        # creating the DataFrame
        all_data = pd.DataFrame(list(zip(player_index, player_name, music_name))) 

        all_data.columns =['抽签序号', '选手姓名', '曲目名称'] #设置列名

        judge_namelist_temp=self.judge_namelist.toPlainText().split('\n')
        for qtable_column in range(int(self.judge_number.text())):
            judge_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
            judge_column_name=judge_namelist_temp[qtable_column]+":"+str(qtable_column+1)+"号评委"
            all_data[judge_column_name]=judge_one_list

        #增加最高分,最低分列 ,增加实际得分列
        if self.remove_yes_radiobox.isChecked()==True:
            max_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['最高分']=max_one_list

            min_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['最低分']=min_one_list

            visual_one_list=[-1]*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['实得分']=visual_one_list

            index_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['最终排名']=index_one_list

            remove_score_str=self.remove_score.text()
            self.remove_score_number=int(self.remove_score.text())
            remove_one_list=[remove_score_str]*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['去掉几个最高分']=remove_one_list
        else:
            visual_one_list=[-1]*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['实得分']=visual_one_list

            index_one_list=[' ']*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['最终排名']=index_one_list

            remove_one_list=['0']*int(self.player_number.text()) #将列数据全部填充为空格
            all_data['去掉几个最高分']=remove_one_list

        all_data['抽签序号']=all_data['抽签序号'].astype(int)
        all_data=all_data.sort_values(by=['抽签序号']) #按照抽签序号排序
        all_data=all_data.reset_index(drop=True) #重新排列一下索引

        all_data.to_excel('temp_data/'+str(self.race_name.text())+'_临时存储数据.xlsx', sheet_name='部分信息', index=True) # index false为不写入索引
        self.all_data_df=all_data

        #界面展示与隐藏
        self.race_prepare.setVisible(False) #初始设置隐藏
        self.race_going.setVisible(True) #初始设置隐藏

        #设置比赛名称
        self.race_going_name.setText(self.race_name.text())

        # 展示当前选手信息,需要读取数据表的1号来展示
        self.current_player.setText("当前选手:1号选手"+str(all_data.loc[0,'选手姓名']))

        #根据评委数量来显示评委框
        judge_number=int(self.judge_number.text())
        judge_one_namelist=self.judge_namelist.toPlainText().split('\n')
        for show_i in range(1,judge_number+1):
            judge_one_label_name="judge_one_label_"+str(show_i)
            judge_one_temp = self.race_going.findChild(QLabel,judge_one_label_name)
            #设置评委label的text
            judge_one_temp.setText(judge_one_namelist[show_i-1]+":"+str(show_i)+"号评委")
            judge_one_temp.setVisible(True)

            judgeone_score_input_name="judgeone_score_input_"+str(show_i)
            judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
            judgeone_score_temp.setVisible(True)

        #根据是否需要去掉最高分和最低分来展示
        if self.remove_yes_radiobox.isChecked()==True:
            #去掉了最高分和最低分,那么就显示所有的
            for show_i in range(1,5):
                judge_com_label_name="judge_com_label_"+str(show_i)
                judge_com_temp = self.race_going.findChild(QLabel,judge_com_label_name)
                judge_com_temp.setVisible(True)
        else:
            #不去掉,则只显示,实际得分
            self.judge_com_average_label.setVisible(True)
            self.judge_com_average.setVisible(True)
        
        return

    #下一个选手
    def func_next_player(self):
        #获取数据,保存这个选手的得分到临时表格中
        all_data_temp=self.all_data_df
        print(self.all_data_df)
        
        #先询问是否计算最终得分,获取输入框信息,计算得分,然后展示出来,展示出来之后将信息保存到临时数据表中
        reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否跳到下一个选手?',QMessageBox.Question)
        if reply_one == QMessageBox.Yes:    
            #先判断选手是否是弃权
            #确定当前计算的是哪个选手,至少有一个评委
            current_player_row=0
            #找到第一个未计分的选手
            player_row=int(all_data_temp.shape[0])
            print("player_row=",player_row)
            for player_row_index in range(0,player_row):
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3]))
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1')
                if str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1' or str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1.0':
                    current_player_row=player_row_index
                    break
                current_player_row=player_row_index

            self.have_score_number=current_player_row+1
            print("current_player_row=",current_player_row)
            print("player_row=",player_row)
            print("self.have_score_number=",self.have_score_number)

            if self.have_score_number==player_row:
                #这时候比赛就提示已经统计完所有选手分数
                self.setQMessageBoxoneButtonTextENToCN("提示","已统计完所有选手分数",QMessageBox.Information)  
                self.current_player.setText("本场比赛所有选手已比赛完毕,请退出程序")
                #保存方法在有最高分和没有最高分时有所不同,有
                judge_number=0
                if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                    judge_number=int(all_data_temp.shape[1])-8
                else:
                    judge_number=int(all_data_temp.shape[1])-6
                #清空分数框
                for show_i in range(1,judge_number+1):
                    judgeone_score_input_name="judgeone_score_input_"+str(show_i)
                    judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
                    judgeone_score_temp.clear()

                    # judgeone_score_temp.setReadOnly(False)  #恢复成可修改

                if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                    #设置最高分
                    self.judge_com_max.setText("最高分: ")
                    #设置最低分
                    self.judge_com_min.setText("最低分: ")
                    #设置最终分数
                    self.judge_com_average.setText(str(''))
                else:
                    #设置最终分数
                    self.judge_com_average.setText(str(''))

                self.judgeone_score_1.setFocus() #设置光标

                #设置按钮不可点击
                self.next_player.setEnabled(False)
                #选手弃权按钮
                self.player_quit.setEnabled(False)


                return
            else:
                judge_number=0
                if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                    judge_number=int(all_data_temp.shape[1])-8
                else:
                    judge_number=int(all_data_temp.shape[1])-6
                #current_player_row表示当前第一个空的数据选手序号,self.have_score_number表示已经填写的选手数据序号,
                # 如果不一样,说明这个选手弃权了,需要把所有数据填写完毕
                # 如果计算数据表里的和当前的一样,那就说明没有弃权
                print("self.have_score_number=",self.have_score_number)
                print("current_player_row=",current_player_row)
                #正常切换,只需要重新设置一些信息即可
                #清空分数框
                for show_i in range(1,judge_number+1):
                    judgeone_score_input_name="judgeone_score_input_"+str(show_i)
                    judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
                    judgeone_score_temp.clear()

                    judgeone_score_temp.setReadOnly(False)  #恢复成可修改
                
                if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                    #重新设置文字信息
                    #设置下一个选手
                    self.current_player.setText("当前选手:"+str(current_player_row+1)+"号选手")
                    #设置最高分
                    self.judge_com_max.setText("最高分: ")
                    #设置最低分
                    self.judge_com_min.setText("最低分: ")
                    #设置最终分数
                    self.judge_com_average.setText(str(''))
                else:
                    #设置下一个选手
                    self.current_player.setText("当前选手:"+str(current_player_row+1)+"号选手")
                    #设置最终分数
                    self.judge_com_average.setText(str(''))
                
                self.judgeone_score_1.setFocus() #设置光标
                return
              
            return
        else:
            self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
            return

        return

    def func_player_quit(self):
        #获取数据,保存这个选手的得分到临时表格中
        all_data_temp=self.all_data_df
        print(self.all_data_df)
        current_player_row=0
        #先询问是否计算最终得分,获取输入框信息,计算得分,然后展示出来,展示出来之后将信息保存到临时数据表中
        reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '当前选手是否弃权?',QMessageBox.Question)
        if reply_one == QMessageBox.Yes:    
            #选手弃权
            judge_number=0
            if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                judge_number=int(all_data_temp.shape[1])-8
            else:
                judge_number=int(all_data_temp.shape[1])-6
            #清空分数框
            for show_i in range(1,judge_number+1):
                judgeone_score_input_name="judgeone_score_input_"+str(show_i)
                judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
                judgeone_score_temp.clear()

            #找到第一个未计分的选手
            player_row=int(all_data_temp.shape[0])
            print("player_row=",player_row)
            for player_row_index in range(0,player_row):
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3]))
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1')
                if str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1' or str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1.0':
                    current_player_row=player_row_index
                    break
                current_player_row=player_row_index

            self.have_score_number=current_player_row
            if self.have_score_number==player_row:
                #这时候比赛就提示已经统计完所有选手分数
                self.setQMessageBoxoneButtonTextENToCN("提示","已统计完所有选手分数",QMessageBox.Information)

                #设置按钮不可点击
                self.next_player.setEnabled(False)
                #选手弃权按钮
                self.player_quit.setEnabled(False)

                return
            else:
                #保存方法在有最高分和没有最高分时有所不同,有
                if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                #将这里面的数据进行覆盖  操作的是save_score_list,score_list_temp_max,score_list_temp_min
                    for judge_number_index in range(0,judge_number):
                        print(judge_number_index)
                        all_data_temp.iloc[current_player_row,judge_number_index+3]=0  
                    
                    all_data_temp.iloc[current_player_row,judge_number_index+4]=0 
                    all_data_temp.iloc[current_player_row,judge_number_index+5]=0
                    all_data_temp.iloc[current_player_row,judge_number_index+6]=0
                else:
                    for judge_number_index in range(0,judge_number):
                        all_data_temp.iloc[current_player_row,judge_number_index+3]=0   
                    
                    all_data_temp.iloc[current_player_row,judge_number_index+4]=0

                print("弃权后all_data_temp=",all_data_temp)
                #重新保存数据表,最后再赋值回去
                all_data_temp.to_excel('temp_data/'+str(self.race_name.text())+'_临时存储数据.xlsx', sheet_name='部分信息', index=True) # index false为不写入索引
                self.all_data_df=all_data_temp

                self.have_score_number=self.have_score_number+1
                self.setQMessageBoxoneButtonTextENToCN("提示",str(current_player_row+1)+"号选手"+str(all_data_temp.loc[current_player_row,'选手姓名'])+"弃权成功,马上跳到下一个选手",QMessageBox.Information)


                if self.have_score_number==player_row:
                    #这时候比赛就提示已经统计完所有选手分数
                    self.setQMessageBoxoneButtonTextENToCN("提示","已统计完所有选手分数",QMessageBox.Information)
                    self.current_player.setText("本场比赛所有选手已比赛完毕,请退出程序")
                    #保存方法在有最高分和没有最高分时有所不同,有
                    #清空分数框
                    for show_i in range(1,judge_number+1):
                        judgeone_score_input_name="judgeone_score_input_"+str(show_i)
                        judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
                        judgeone_score_temp.clear()

                    if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                        #设置最高分
                        self.judge_com_max.setText("最高分: ")
                        #设置最低分
                        self.judge_com_min.setText("最低分: ")
                        #设置最终分数
                        self.judge_com_average.setText(str(''))
                    else:
                        #设置最终分数
                        self.judge_com_average.setText(str(''))

                    self.judgeone_score_1.setFocus() #设置光标

                    #设置按钮不可点击
                    self.next_player.setEnabled(False)
                    #选手弃权按钮
                    self.player_quit.setEnabled(False)

                    return
                else:
                    #跳转到下一个选手
                    if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                        self.current_player.setText("当前选手:"+str(current_player_row+2)+"号选手"+str(all_data_temp.loc[current_player_row+1,'选手姓名']))
                        #设置最高分
                        self.judge_com_max.setText("最高分: ")
                        #设置最低分
                        self.judge_com_min.setText("最低分: ")
                        #设置最终分数
                        self.judge_com_average.setText(str(''))
                    else:
                        #设置下一个选手
                        self.current_player.setText("当前选手:"+str(current_player_row+2)+"号选手"+str(all_data_temp.loc[current_player_row+1,'选手姓名']))
                        #设置最终分数
                        self.judge_com_average.setText(str(''))

                    self.judgeone_score_1.setFocus() #设置光标
                    


                return
        else:
            self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
            return

    #结束比赛
    def func_exit_race(self):
        #获取数据,保存这个选手的得分到临时表格中
        all_data_temp=self.all_data_df
        print(self.all_data_df)
        
        reply_zero=self.setQMessageappENToCN('提示', '请选择退出程序的原因?',QMessageBox.Question)
        if reply_zero == QMessageBox.Yes:
            reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否确认选择比赛暂停?',QMessageBox.Question)
            if reply_one == QMessageBox.Yes: 
                self.setQMessageBoxoneButtonTextENToCN("提示","比赛暂停,临时数据保存成功",QMessageBox.Information)
                sys.exit(0)
                return
            else:
                self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
                return
            return
        else:
            reply_two=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否确认选择比赛结束?',QMessageBox.Question)
            if reply_two == QMessageBox.Yes: 
                #导出数据,清空临时表
                all_data_temp=all_data_temp.sort_values(by=['实得分'],ascending=False) #按照抽签序号排序
                all_data_temp=all_data_temp.reset_index(drop=True) #重新排列一下索引
                
                player_row=int(all_data_temp.shape[0])
                print("player_row=",player_row)
                for player_row_index in range(0,player_row):
                    all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-2]=player_row_index+1

                all_data_temp.to_excel('save_data/'+str(self.race_name.text())+'_最终数据全部备份版.xlsx', sheet_name='部分信息', index=True) # index false为不写入索引
                #保留特定数据
                all_data_temp_new = all_data_temp[['抽签序号', '选手姓名', '曲目名称','实得分','最终排名']]
                
                # 创建一个新的文档
                doc_part=docx.Document()
                # 添加标题
                para_heading=doc_part.add_heading(str(self.race_name.text()), 5)
                para_heading.alignment=docx.enum.text.WD_ALIGN_PARAGRAPH.CENTER#设置为左对齐


                # 添加表格
                table_part = doc_part.add_table(rows=all_data_temp_new.shape[0]+1, cols=all_data_temp_new.shape[1])

                # 添加表头
                hdr_cells = table_part.rows[0].cells
                for i in range(all_data_temp_new.shape[1]):
                    hdr_cells[i].text = all_data_temp_new.columns[i]

                # 添加每一行数据
                for i in range(all_data_temp_new.shape[0]):
                    row_cells = table_part.rows[i+1].cells
                    for j in range(all_data_temp_new.shape[1]):
                        row_cells[j].text = str(all_data_temp_new.values[i,j])

                # 保存文件
                doc_part.save('save_data/'+str(self.race_name.text())+'_最终数据简洁版.docx')
                # del_files("temp_data/")
                self.setQMessageBoxoneButtonTextENToCN("提示","最终数据导出成功,本次比赛临时数据已清除",QMessageBox.Information)
                sys.exit(0)
                return
            else:
                self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
                return
            return

        return

    #根据文件来读取信息,这个是不一样的,最后写才对,这个继续前次比赛,比赛的信息设置与全新比赛不相同
    def func_continue_race(self):
        #先是询问是否继续上次比赛
        reply_one=self.setQMessageBoxtwoButtonTextENToCN('提示', '是否继续上次比赛?',QMessageBox.Question)
        if reply_one == QMessageBox.Yes:        
            folderName, _ = QFileDialog.getOpenFileName(self, "选择xlsx文件", "", "*.xlsx")        
            race_name=folderName.split("/")[-1].split("_")[0]
            self.race_name.setText(race_name)
            self.all_data_df=pd.read_excel('temp_data/'+folderName.split("/")[-1],index_col=0)
            
            all_data_temp=self.all_data_df

            #界面展示与隐藏
            self.race_prepare.setVisible(False) #初始设置隐藏
            self.race_going.setVisible(True) #初始设置隐藏

            #设置比赛名称
            self.race_going_name.setText(race_name)

            #设置选手初值
            current_player_row=0
            #找到第一个未计分的选手
            player_row=int(all_data_temp.shape[0])
            print("player_row=",player_row)
            for player_row_index in range(0,player_row):
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3]))
                print(str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1')
                if str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1' or str(all_data_temp.iloc[player_row_index,int(all_data_temp.shape[1])-3])=='-1.0':
                    current_player_row=player_row_index
                    break
                current_player_row=player_row_index

            self.have_score_number=current_player_row
            judge_number=0

            self.remove_score_number=int(all_data_temp.loc[0,'去掉几个最高分'])
            
            #设置界面信息:当前选手,是否展示实得分最高分,评委名字
            if int(all_data_temp.loc[0,'去掉几个最高分'])>0:
                self.current_player.setText("当前选手:"+str(current_player_row+1)+"号选手")
                for show_i in range(1,5):
                    judge_com_label_name="judge_com_label_"+str(show_i)
                    judge_com_temp = self.race_going.findChild(QLabel,judge_com_label_name)
                    judge_com_temp.setVisible(True)
                #设置最高分
                self.judge_com_max.setText("最高分: ")
                #设置最低分
                self.judge_com_min.setText("最低分: ")
                #设置最终分数
                self.judge_com_average.setText(str(''))
                judge_number=int(all_data_temp.shape[1])-8
            else:
                #设置下一个选手
                self.current_player.setText("当前选手:"+str(current_player_row+1)+"号选手")
                self.judge_com_average_label.setVisible(True)
                self.judge_com_average.setVisible(True)
                #设置最终分数
                self.judge_com_average.setText(str(''))
                judge_number=int(all_data_temp.shape[1])-6

            judge_namelist=[column for column in all_data_temp]
            judge_one_namelist=judge_namelist[3:3+judge_number]
            for show_i in range(1,judge_number+1):
                judge_one_label_name="judge_one_label_"+str(show_i)
                judge_one_temp = self.race_going.findChild(QLabel,judge_one_label_name)
                #设置评委label的text
                judge_one_temp.setText(judge_one_namelist[show_i-1].split(":")[0]+":"+str(show_i)+"号评委")
                judge_one_temp.setVisible(True)

                judgeone_score_input_name="judgeone_score_input_"+str(show_i)
                judgeone_score_temp = self.race_going.findChild(QLineEdit,judgeone_score_input_name)
                judgeone_score_temp.setVisible(True)

        else:
            self.setQMessageBoxoneButtonTextENToCN("提示","用户取消操作",QMessageBox.Information)
        return


if __name__ == '__main__':
    app=QApplication(sys.argv)  
    w = MyWindow()
    w.ui.show()
    app.exec()

程序打包成exe

指令 安装pyinstall库

文件目录
根路径
	getscore.py
	assets
		xxx.ui
	save_data
	temp_data
	

pyinstaller -F -w getscore.py --add-data ".\\assets\\*;.\\assets"

参考文章

感谢以下作者的知识分享

PyQt入门教程 - 随笔分类 - 锅边糊 - 博客园 (cnblogs.com)

【创作不易,望点赞收藏,若有疑问,请留言,谢谢】

与使用pyqt5制作简单计分桌面应用相似的内容:

使用pyqt5制作简单计分桌面应用

这是一个自己写的使用pyqt5制作简单计分桌面应用的实例,包含完整代码,希望对大家有所帮助。制作这个小程序的起因是因为有个艺术类比赛需要设计这个一个桌面程序,方便统分。

pyqt5 子线程如何操作主线程GUI

一.简介 在使用pyqt5编写gui时遇到两个问题,会导致界面崩溃,今天就围绕这两个问题来简单说明和改进。 1.在主线程中使用while无限循环会导致界面崩溃 2.在子线程中操作主线程gui会导致界面崩溃 二.步骤说明 1.在主线程中使用while无限循环会导致界面崩溃 1)错误代码 import

PyQt5 GUI编程(组件使用)

一.简介 PyQt5 是一个用于创建图形用户界面(GUI)应用程序的 Python 绑定,它基于 Qt 库。PyQt5 提供了大量的组件(也称为控件或部件),用于构建复杂的用户界面。以下是一些常用的 PyQt5 组件 二.组件用法 1.数字组件(QLCDNumber) class FileChoos

使用Cloudflare Worker加速docker镜像

前言 开发者越来越难了,现在国内的docker镜像也都️了,没有镜像要使用docker太难了,代理又很慢 现在就只剩下自建镜像的办法了 GitHub上有开源项目可以快速搭建自己的镜像库,不过还是有点麻烦,还好Cloudflare暂时还活着‍ 本文记录一下使用 Cloudf

使用C#/.NET解析Wiki百科数据实现获取历史上的今天

创建一个webapi项目做测试使用。 创建新控制器,搭建一个基础框架,包括获取当天日期、wiki的请求地址等 创建一个Http请求帮助类以及方法,用于获取指定URL的信息 使用http请求访问指定url,先运行一下,看看返回的内容。内容如图右边所示,实际上是一个Json数据。我们主要解析 大事记 部

Pybind11和CMake构建python扩展模块环境搭建

使用pybind11的CMake模板来创建拓展环境搭建 从Github上下载cmake_example的模板,切换分支,并升级pybind11子模块到最新版本 拉取pybind11使用cmake构建工具的模板仓库 git clone --recursive https://github.com/mr

说说RabbitMQ延迟队列实现原理?

使用 RabbitMQ 和 RocketMQ 的人是幸运的,因为这两个 MQ 自身提供了延迟队列的实现,不像用 Kafka 的同学那么苦逼,还要自己实现延迟队列。当然,这都是题外话,今天咱们重点来聊聊 RabbitMQ 延迟队列的实现原理,以及 RabbitMQ 实现延迟队列的优缺点有哪些? 很多人

使用FModel提取游戏资产

目录前言FModel简介FModel安装FModel使用初次使用资产预览资产导出附录dumperDumper-7生成usmap文件向游戏中注入dll 前言 这篇文章仅记录我作为初学者使用FModel工具提取某款游戏模型的过程。 FModel简介 FModel是一个开源软件,可以用于查看和提取UE4-

使用GSAP制作动画视频

GSAP 3Blue1Brown给我留下了深刻印象。利用动画制作视频,内容简洁,演示清晰。前两天刚好碰到一件事,我就顺便学习了一下怎么用代码做动画。 以javascrip为例,有两个动画引擎,GSAP和Animajs。由于网速的原因,询问了GPT后,我选择了GSAP来制作我的第一个动画视频。 制作动

使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类就这么简单!

前言 今天大姚给大家分享一个.NET开源、免费、跨平台(支持Windows、Linux、macOS多个操作系统)的机器学习框架:ML.NET。并且本文将会带你快速使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类。 ML.NET框架介绍 ML.NET 允许开发人员在其 .NET 应用程序