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

这是一个自己写的使用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)

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

posted @ 2024-07-11 14:38  东血  阅读(413)  评论(2编辑  收藏  举报

载入天数...载入时分秒...