Compare commits

..

No commits in common. "master" and "1.0" have entirely different histories.
master ... 1.0

19 changed files with 20524 additions and 183 deletions

3
.gitignore vendored
View File

@ -1,3 +0,0 @@
/yun/build/
/yun/dist/
/yun/client.spec

View File

@ -3,9 +3,7 @@
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="21c1c7ee:193388d497c:-7ff9" />
<option name="userId" value="-e5ede7a:1972005fd59:-7ffa" />
</MTProjectMetadataState>
</option>
</component>

View File

@ -1,103 +1,7 @@
# 十秒挑战 使用说明文档
---
## 版本一:本地无数据持久化基础版本(无排行榜)
```txt
- base
|- base.py
|- 十秒挑战.png
|- 按钮.png
```
### 功能简介
* 支持计时开始与停止,计算玩家的实际用时。
* 显示用时及与目标10秒的误差。
* 无排行榜及成绩保存功能。
### 使用说明
1. 运行程序。
2. 点击“开始/停止”按钮开始计时,再次点击停止计时。
3. 程序显示您的用时及误差。
### 适用场景
* 适合练习时间感知,无需保存成绩的简单场景。
---
## 版本二:本地持久化数据版本
```txt
|- app.py
|- leaderboard.json
```
### 功能简介
* 包含基础版本的计时功能。
* 停止计时后,输入玩家姓名,成绩保存至本地 `leaderboard.json` 文件。
* 读取本地数据文件,显示排行榜,误差越小排名越靠前。
* 本地实现排行榜数据持久化。
### 使用说明
1. 运行程序。
2. 点击“开始/停止”按钮计时。
3. 结束后输入姓名,成绩保存到本地。
4. 排行榜自动更新并显示本地最佳成绩。
### 适用场景
* 适合单机使用,需保存成绩但无网络依赖的情况。
---
## 版本三:云端持久化数据版本
```txt
|- yun
|- server.py
|- client.py
|- icon.ico
```
### 功能简介
* 保留基础计时功能。
* 停止计时后输入姓名,成绩通过 HTTP 请求提交到云端 Flask 服务器。
* 云端统一存储和管理排行榜数据。
* 客户端定期从云端加载排行榜,显示最新排名。
### 使用说明
1. 启动云端 Flask 服务器,或使用提供的服务器地址。
2. 运行客户端程序,点击“开始/停止”按钮计时。
3. 结束计时后输入姓名,成绩自动提交服务器。
4. 排行榜实时从云端获取并更新显示。
### 适用场景
* 适合多人在线成绩同步,支持跨设备查看和比较。
---
## 打包示例命令
```bash
pyinstaller -F -w -i icon.ico client.py
```
## 生成依赖文件命令
```bash
pip freeze > requirements.txt
```
```bash
pip install requests -i https://mirrors.aliyun.com/pypi/simple/
```

3578
build/client/Analysis-00.toc Normal file

File diff suppressed because it is too large Load Diff

3042
build/client/EXE-00.toc Normal file

File diff suppressed because it is too large Load Diff

3020
build/client/PKG-00.toc Normal file

File diff suppressed because it is too large Load Diff

BIN
build/client/PYZ-00.pyz Normal file

Binary file not shown.

577
build/client/PYZ-00.toc Normal file
View File

@ -0,0 +1,577 @@
('C:\\sairateproject\\TenSecondChallenge\\build\\client\\PYZ-00.pyz',
[('__future__',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\__future__.py',
'PYMODULE'),
('_compat_pickle',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\_compat_pickle.py',
'PYMODULE'),
('_compression',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\_compression.py',
'PYMODULE'),
('_py_abc',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\_py_abc.py',
'PYMODULE'),
('_pydecimal',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\_pydecimal.py',
'PYMODULE'),
('_strptime',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\_strptime.py',
'PYMODULE'),
('_threading_local',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\_threading_local.py',
'PYMODULE'),
('argparse',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\argparse.py',
'PYMODULE'),
('ast',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\ast.py',
'PYMODULE'),
('base64',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\base64.py',
'PYMODULE'),
('bisect',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\bisect.py',
'PYMODULE'),
('bz2',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\bz2.py',
'PYMODULE'),
('calendar',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\calendar.py',
'PYMODULE'),
('certifi',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\certifi\\__init__.py',
'PYMODULE'),
('certifi.core',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\certifi\\core.py',
'PYMODULE'),
('charset_normalizer',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\__init__.py',
'PYMODULE'),
('charset_normalizer.api',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\api.py',
'PYMODULE'),
('charset_normalizer.cd',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\cd.py',
'PYMODULE'),
('charset_normalizer.constant',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\constant.py',
'PYMODULE'),
('charset_normalizer.legacy',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\legacy.py',
'PYMODULE'),
('charset_normalizer.models',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\models.py',
'PYMODULE'),
('charset_normalizer.utils',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\utils.py',
'PYMODULE'),
('charset_normalizer.version',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\charset_normalizer\\version.py',
'PYMODULE'),
('contextlib',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\contextlib.py',
'PYMODULE'),
('contextvars',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\contextvars.py',
'PYMODULE'),
('copy',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\copy.py',
'PYMODULE'),
('csv',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\csv.py',
'PYMODULE'),
('dataclasses',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\dataclasses.py',
'PYMODULE'),
('datetime',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\datetime.py',
'PYMODULE'),
('decimal',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\decimal.py',
'PYMODULE'),
('dis',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\dis.py',
'PYMODULE'),
('email',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\__init__.py',
'PYMODULE'),
('email._encoded_words',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\_encoded_words.py',
'PYMODULE'),
('email._header_value_parser',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\_header_value_parser.py',
'PYMODULE'),
('email._parseaddr',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\_parseaddr.py',
'PYMODULE'),
('email._policybase',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\_policybase.py',
'PYMODULE'),
('email.base64mime',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\base64mime.py',
'PYMODULE'),
('email.charset',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\charset.py',
'PYMODULE'),
('email.contentmanager',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\contentmanager.py',
'PYMODULE'),
('email.encoders',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\encoders.py',
'PYMODULE'),
('email.errors',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\errors.py',
'PYMODULE'),
('email.feedparser',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\feedparser.py',
'PYMODULE'),
('email.generator',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\generator.py',
'PYMODULE'),
('email.header',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\header.py',
'PYMODULE'),
('email.headerregistry',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\headerregistry.py',
'PYMODULE'),
('email.iterators',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\iterators.py',
'PYMODULE'),
('email.message',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\message.py',
'PYMODULE'),
('email.parser',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\parser.py',
'PYMODULE'),
('email.policy',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\policy.py',
'PYMODULE'),
('email.quoprimime',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\quoprimime.py',
'PYMODULE'),
('email.utils',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\email\\utils.py',
'PYMODULE'),
('fnmatch',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\fnmatch.py',
'PYMODULE'),
('fractions',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\fractions.py',
'PYMODULE'),
('ftplib',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\ftplib.py',
'PYMODULE'),
('getopt',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\getopt.py',
'PYMODULE'),
('getpass',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\getpass.py',
'PYMODULE'),
('gettext',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\gettext.py',
'PYMODULE'),
('gzip',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\gzip.py',
'PYMODULE'),
('hashlib',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\hashlib.py',
'PYMODULE'),
('hmac',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\hmac.py',
'PYMODULE'),
('http',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\http\\__init__.py',
'PYMODULE'),
('http.client',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\http\\client.py',
'PYMODULE'),
('http.cookiejar',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\http\\cookiejar.py',
'PYMODULE'),
('http.cookies',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\http\\cookies.py',
'PYMODULE'),
('idna',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\idna\\__init__.py',
'PYMODULE'),
('idna.core',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\idna\\core.py',
'PYMODULE'),
('idna.idnadata',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\idna\\idnadata.py',
'PYMODULE'),
('idna.intranges',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\idna\\intranges.py',
'PYMODULE'),
('idna.package_data',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\idna\\package_data.py',
'PYMODULE'),
('idna.uts46data',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\idna\\uts46data.py',
'PYMODULE'),
('importlib',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\__init__.py',
'PYMODULE'),
('importlib._abc',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\_abc.py',
'PYMODULE'),
('importlib._adapters',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\_adapters.py',
'PYMODULE'),
('importlib._bootstrap',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\_bootstrap.py',
'PYMODULE'),
('importlib._bootstrap_external',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\_bootstrap_external.py',
'PYMODULE'),
('importlib._common',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\_common.py',
'PYMODULE'),
('importlib.abc',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\abc.py',
'PYMODULE'),
('importlib.machinery',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\machinery.py',
'PYMODULE'),
('importlib.metadata',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\__init__.py',
'PYMODULE'),
('importlib.metadata._adapters',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\_adapters.py',
'PYMODULE'),
('importlib.metadata._collections',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\_collections.py',
'PYMODULE'),
('importlib.metadata._functools',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\_functools.py',
'PYMODULE'),
('importlib.metadata._itertools',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\_itertools.py',
'PYMODULE'),
('importlib.metadata._meta',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\_meta.py',
'PYMODULE'),
('importlib.metadata._text',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\metadata\\_text.py',
'PYMODULE'),
('importlib.readers',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\readers.py',
'PYMODULE'),
('importlib.resources',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\resources.py',
'PYMODULE'),
('importlib.util',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\importlib\\util.py',
'PYMODULE'),
('inspect',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\inspect.py',
'PYMODULE'),
('ipaddress',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\ipaddress.py',
'PYMODULE'),
('json',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\__init__.py',
'PYMODULE'),
('json.decoder',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\decoder.py',
'PYMODULE'),
('json.encoder',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\encoder.py',
'PYMODULE'),
('json.scanner',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\json\\scanner.py',
'PYMODULE'),
('logging',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\logging\\__init__.py',
'PYMODULE'),
('lzma',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\lzma.py',
'PYMODULE'),
('mimetypes',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\mimetypes.py',
'PYMODULE'),
('netrc',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\netrc.py',
'PYMODULE'),
('nturl2path',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\nturl2path.py',
'PYMODULE'),
('numbers',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\numbers.py',
'PYMODULE'),
('opcode',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\opcode.py',
'PYMODULE'),
('optparse',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\optparse.py',
'PYMODULE'),
('pathlib',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\pathlib.py',
'PYMODULE'),
('pickle',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\pickle.py',
'PYMODULE'),
('pprint',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\pprint.py',
'PYMODULE'),
('py_compile',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\py_compile.py',
'PYMODULE'),
('queue',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\queue.py',
'PYMODULE'),
('quopri',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\quopri.py',
'PYMODULE'),
('random',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\random.py',
'PYMODULE'),
('requests',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\__init__.py',
'PYMODULE'),
('requests.__version__',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\__version__.py',
'PYMODULE'),
('requests._internal_utils',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\_internal_utils.py',
'PYMODULE'),
('requests.adapters',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\adapters.py',
'PYMODULE'),
('requests.api',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\api.py',
'PYMODULE'),
('requests.auth',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\auth.py',
'PYMODULE'),
('requests.certs',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\certs.py',
'PYMODULE'),
('requests.compat',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\compat.py',
'PYMODULE'),
('requests.cookies',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\cookies.py',
'PYMODULE'),
('requests.exceptions',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\exceptions.py',
'PYMODULE'),
('requests.hooks',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\hooks.py',
'PYMODULE'),
('requests.models',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\models.py',
'PYMODULE'),
('requests.packages',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\packages.py',
'PYMODULE'),
('requests.sessions',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\sessions.py',
'PYMODULE'),
('requests.status_codes',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\status_codes.py',
'PYMODULE'),
('requests.structures',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\structures.py',
'PYMODULE'),
('requests.utils',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\requests\\utils.py',
'PYMODULE'),
('selectors',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\selectors.py',
'PYMODULE'),
('shlex',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\shlex.py',
'PYMODULE'),
('shutil',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\shutil.py',
'PYMODULE'),
('signal',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\signal.py',
'PYMODULE'),
('socket',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\socket.py',
'PYMODULE'),
('ssl',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\ssl.py',
'PYMODULE'),
('statistics',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\statistics.py',
'PYMODULE'),
('string',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\string.py',
'PYMODULE'),
('stringprep',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\stringprep.py',
'PYMODULE'),
('subprocess',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\subprocess.py',
'PYMODULE'),
('tarfile',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tarfile.py',
'PYMODULE'),
('tempfile',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tempfile.py',
'PYMODULE'),
('textwrap',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\textwrap.py',
'PYMODULE'),
('threading',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\threading.py',
'PYMODULE'),
('tkinter',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tkinter\\__init__.py',
'PYMODULE'),
('tkinter.commondialog',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tkinter\\commondialog.py',
'PYMODULE'),
('tkinter.constants',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tkinter\\constants.py',
'PYMODULE'),
('tkinter.messagebox',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tkinter\\messagebox.py',
'PYMODULE'),
('tkinter.simpledialog',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tkinter\\simpledialog.py',
'PYMODULE'),
('token',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\token.py',
'PYMODULE'),
('tokenize',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tokenize.py',
'PYMODULE'),
('tracemalloc',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\tracemalloc.py',
'PYMODULE'),
('typing',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\typing.py',
'PYMODULE'),
('urllib',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\urllib\\__init__.py',
'PYMODULE'),
('urllib.error',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\urllib\\error.py',
'PYMODULE'),
('urllib.parse',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\urllib\\parse.py',
'PYMODULE'),
('urllib.request',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\urllib\\request.py',
'PYMODULE'),
('urllib.response',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\urllib\\response.py',
'PYMODULE'),
('urllib3',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\__init__.py',
'PYMODULE'),
('urllib3._base_connection',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\_base_connection.py',
'PYMODULE'),
('urllib3._collections',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\_collections.py',
'PYMODULE'),
('urllib3._request_methods',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\_request_methods.py',
'PYMODULE'),
('urllib3._version',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\_version.py',
'PYMODULE'),
('urllib3.connection',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\connection.py',
'PYMODULE'),
('urllib3.connectionpool',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\connectionpool.py',
'PYMODULE'),
('urllib3.contrib',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\__init__.py',
'PYMODULE'),
('urllib3.contrib.emscripten',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\emscripten\\__init__.py',
'PYMODULE'),
('urllib3.contrib.emscripten.connection',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\emscripten\\connection.py',
'PYMODULE'),
('urllib3.contrib.emscripten.fetch',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\emscripten\\fetch.py',
'PYMODULE'),
('urllib3.contrib.emscripten.request',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\emscripten\\request.py',
'PYMODULE'),
('urllib3.contrib.emscripten.response',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\emscripten\\response.py',
'PYMODULE'),
('urllib3.contrib.pyopenssl',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\pyopenssl.py',
'PYMODULE'),
('urllib3.contrib.socks',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\contrib\\socks.py',
'PYMODULE'),
('urllib3.exceptions',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\exceptions.py',
'PYMODULE'),
('urllib3.fields',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\fields.py',
'PYMODULE'),
('urllib3.filepost',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\filepost.py',
'PYMODULE'),
('urllib3.http2',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\http2\\__init__.py',
'PYMODULE'),
('urllib3.http2.connection',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\http2\\connection.py',
'PYMODULE'),
('urllib3.http2.probe',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\http2\\probe.py',
'PYMODULE'),
('urllib3.poolmanager',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\poolmanager.py',
'PYMODULE'),
('urllib3.response',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\response.py',
'PYMODULE'),
('urllib3.util',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\__init__.py',
'PYMODULE'),
('urllib3.util.connection',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\connection.py',
'PYMODULE'),
('urllib3.util.proxy',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\proxy.py',
'PYMODULE'),
('urllib3.util.request',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\request.py',
'PYMODULE'),
('urllib3.util.response',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\response.py',
'PYMODULE'),
('urllib3.util.retry',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\retry.py',
'PYMODULE'),
('urllib3.util.ssl_',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\ssl_.py',
'PYMODULE'),
('urllib3.util.ssl_match_hostname',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\ssl_match_hostname.py',
'PYMODULE'),
('urllib3.util.ssltransport',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\ssltransport.py',
'PYMODULE'),
('urllib3.util.timeout',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\timeout.py',
'PYMODULE'),
('urllib3.util.url',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\url.py',
'PYMODULE'),
('urllib3.util.util',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\util.py',
'PYMODULE'),
('urllib3.util.wait',
'C:\\sairateproject\\TenSecondChallenge\\.venv\\lib\\site-packages\\urllib3\\util\\wait.py',
'PYMODULE'),
('uu',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\uu.py',
'PYMODULE'),
('zipfile',
'C:\\Users\\sairate\\AppData\\Local\\Programs\\Python\\Python310\\lib\\zipfile.py',
'PYMODULE')])

Binary file not shown.

BIN
build/client/client.pkg Normal file

Binary file not shown.

View File

@ -0,0 +1,48 @@
This file lists modules PyInstaller was not able to find. This does not
necessarily mean this module is required for running your program. Python and
Python 3rd-party packages include a lot of conditional or optional modules. For
example the module 'ntpath' only exists on Windows, whereas the module
'posixpath' only exists on Posix systems.
Types if import:
* top-level: imported at the top-level - look at these first
* conditional: imported within an if-statement
* delayed: imported within a function
* optional: imported within a try-except-statement
IMPORTANT: Do NOT post this list to the issue-tracker. Use it as a basis for
tracking down the missing module yourself. Thanks!
missing module named 'org.python' - imported by copy (optional)
missing module named org - imported by pickle (optional)
missing module named _frozen_importlib_external - imported by importlib._bootstrap (delayed), importlib (optional), importlib.abc (optional)
excluded module named _frozen_importlib - imported by importlib (optional), importlib.abc (optional)
missing module named pep517 - imported by importlib.metadata (delayed)
missing module named posix - imported by os (conditional, optional), shutil (conditional), importlib._bootstrap_external (conditional)
missing module named resource - imported by posix (top-level)
missing module named grp - imported by subprocess (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional)
missing module named pwd - imported by posixpath (delayed, conditional), subprocess (delayed, conditional, optional), shutil (delayed, optional), tarfile (optional), pathlib (delayed, optional), netrc (delayed, conditional), getpass (delayed)
missing module named _posixsubprocess - imported by subprocess (optional)
missing module named fcntl - imported by subprocess (optional)
missing module named _scproxy - imported by urllib.request (conditional)
missing module named termios - imported by getpass (optional)
missing module named simplejson - imported by requests.compat (conditional, optional)
missing module named dummy_threading - imported by requests.cookies (optional)
missing module named typing_extensions - imported by urllib3.util.retry (conditional), urllib3._collections (conditional), urllib3.util.ssltransport (conditional), urllib3.connectionpool (conditional), urllib3.poolmanager (conditional), urllib3.contrib.emscripten.fetch (conditional), charset_normalizer.legacy (conditional)
missing module named 'h2.events' - imported by urllib3.http2.connection (top-level)
missing module named 'h2.connection' - imported by urllib3.http2.connection (top-level)
missing module named h2 - imported by urllib3.http2.connection (top-level)
missing module named zstandard - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotli - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named brotlicffi - imported by urllib3.util.request (optional), urllib3.response (optional)
missing module named socks - imported by urllib3.contrib.socks (optional)
missing module named 'typing.io' - imported by importlib.resources (top-level)
missing module named cryptography - imported by urllib3.contrib.pyopenssl (top-level), requests (conditional, optional)
missing module named 'OpenSSL.crypto' - imported by urllib3.contrib.pyopenssl (delayed, conditional)
missing module named 'cryptography.x509' - imported by urllib3.contrib.pyopenssl (delayed, optional)
missing module named OpenSSL - imported by urllib3.contrib.pyopenssl (top-level)
missing module named chardet - imported by requests (optional)
missing module named 'pyodide.ffi' - imported by urllib3.contrib.emscripten.fetch (delayed, optional)
missing module named pyodide - imported by urllib3.contrib.emscripten.fetch (top-level)
missing module named js - imported by urllib3.contrib.emscripten.fetch (top-level)

10178
build/client/xref-client.html Normal file

File diff suppressed because it is too large Load Diff

BIN
dist/client.exe vendored Normal file

Binary file not shown.

View File

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

Before

Width:  |  Height:  |  Size: 162 KiB

After

Width:  |  Height:  |  Size: 162 KiB

View File

@ -3,8 +3,9 @@ from tkinter import messagebox, simpledialog
import time
import requests
API_URL = "http://47.80.30.142:6364/"
API_URL = "http://47.80.30.142:6364" # Flask 接口地址
# 读取排行榜数据(从 Flask 获取)
def load_leaderboard():
try:
resp = requests.get(f"{API_URL}/get_board")
@ -16,62 +17,52 @@ def load_leaderboard():
messagebox.showerror("错误", f"无法加载排行榜数据:{e}")
return []
# 获取参赛者姓名
def get_player_name():
name = simpledialog.askstring("参赛者姓名", "请输入您的姓名:")
if not name:
messagebox.showwarning("警告", "姓名不能为空")
messagebox.showwarning("警告", "姓名不能为空,请重新输入。")
return get_player_name()
return name
def get_player_message():
return simpledialog.askstring("祝贺留言", "你太棒了!要留下什么话?")
def submit_result(name, error, message=None):
# 上传成绩并刷新排行榜
def submit_result(name, error):
try:
# 先下载当前排行榜
leaderboard = load_leaderboard()
updated = False
# 查找或更新当前用户成绩(误差更小的)
found = False
for entry in leaderboard:
if entry["name"] == name:
found = True
if abs(error) < entry["error"]:
entry["error"] = round(abs(error), 3)
if abs(error) < 0.1 and message:
entry["message"] = message
updated = True
break
if not updated:
entry = {"name": name, "error": round(abs(error), 3)}
if abs(error) < 0.1 and message:
entry["message"] = message
leaderboard.append(entry)
if not found:
leaderboard.append({"name": name, "error": round(abs(error), 3)})
# 按误差升序排序
leaderboard.sort(key=lambda x: x["error"])
# 提交新的排行榜到服务器
resp = requests.post(f"{API_URL}/set_board", json=leaderboard)
if resp.status_code == 200:
update_rank_display(leaderboard)
update_message_display(leaderboard)
else:
messagebox.showerror("提交失败", "成绩上传失败")
messagebox.showerror("提交失败", "提交成绩失败,请稍后再试。")
except Exception as e:
messagebox.showerror("错误", f"提交成绩时出错:{e}")
# 显示排行榜
def update_rank_display(leaderboard):
rank_listbox.delete(0, tk.END)
for i, entry in enumerate(leaderboard, 1):
rank_listbox.insert(tk.END, f"{i}. {entry['name']:<8} 误差: {entry['error']:.3f}s")
def update_message_display(leaderboard):
messages.clear()
for entry in leaderboard:
if "message" in entry and entry["message"]:
messages.append(f"{entry['name']}{entry['message']}")
def scroll_messages():
if messages:
msg = messages.pop(0)
message_var.set(msg)
messages.append(msg)
root.after(3000, scroll_messages)
n, e = entry["name"], entry["error"]
rank_listbox.insert(tk.END, f"{i}. {n:<8} 误差: {e:.3f}s")
# 更新时间函数
def update_time():
if flag:
now = time.time()
@ -81,13 +72,30 @@ def update_time():
def show_win_animation():
anim = tk.Toplevel(root)
anim.geometry("300x150")
anim.configure(bg="white")
tk.Label(anim, text="🎉 完美掌控时间!", font=("微软雅黑", 18, "bold"), bg="white").pack(expand=True)
anim.after(1500, anim.destroy)
anim.geometry("320x200")
anim.title("🎉 胜利动画")
anim.configure(bg="#ffffff")
anim.attributes("-topmost", True)
label = tk.Label(anim, text="🎉 完美掌控时间!🎉", font=("微软雅黑", 18, "bold"), bg="#ffffff")
label.pack(expand=True)
colors = ["#ff6666", "#66cc66", "#3399ff", "#ffcc00", "#cc66ff"]
sizes = [18, 22, 26, 30, 26, 22, 18]
def animate(i=0):
if i < len(sizes):
label.config(font=("微软雅黑", sizes[i], "bold"), fg=colors[i % len(colors)])
anim.after(150, animate, i + 1)
else:
anim.destroy()
animate()
# 控制开始/停止
def change():
global flag, start_time
if not flag:
flag = True
start_time = time.time()
@ -97,57 +105,57 @@ def change():
end_time = time.time()
timex = end_time - start_time
error = timex - 10
timex_label.config(text=f"✅ 实际时间:{timex:.3f}\n误差:{error:.3f}")
name = get_player_name()
message = None
if abs(error) < 0.1:
message = get_player_message()
submit_result(name, error)
if abs(error) < 0.01:
show_win_animation()
else:
messagebox.showinfo("结果", "再接再厉!")
submit_result(name, error, message)
messagebox.showinfo("结果", "还差一点点,再接再厉吧!")
# ============================ UI ============================
# ================================
# 主窗口
# ================================
root = tk.Tk()
root.geometry("400x550")
root.geometry("340x500")
root.title("10秒挑战")
root.configure(bg="#f0faff")
title_label = tk.Label(root, text="🎯 10 秒挑战 🎯", font=("微软雅黑", 18, "bold"), bg="#f0faff", fg="#004466")
title_label.pack(pady=10)
# 标题
title_label = tk.Label(root, text="🎯 10 秒挑战 🎯", font=("微软雅黑", 18, "bold"), fg="#004466", bg="#f0faff")
title_label.pack(pady=15)
# 排行榜框
rank_frame = tk.Frame(root, bg="#ffffff", bd=2, relief="groove")
rank_frame.pack(pady=5)
rank_frame.pack(pady=10)
rank_title = tk.Label(rank_frame, text="🏆 排行榜", font=("微软雅黑", 10, "bold"), bg="#ffffff")
rank_title.pack(pady=5)
rank_title = tk.Label(rank_frame, text="🏆 排行榜(误差越小越靠前)", font=("微软雅黑", 10, "bold"), bg="#ffffff", fg="#333333")
rank_title.pack(pady=(5, 0))
rank_listbox = tk.Listbox(rank_frame, font=("Courier", 10), height=5, width=35, bg="#f9f9f9")
rank_listbox.pack(padx=10, pady=5)
timex_label = tk.Label(root, text="点击按钮开始挑战", font=("微软雅黑", 12), bg="#f0faff")
timex_label.pack(pady=20)
start_button = tk.Button(root, text="🎮 开始 / 停止", font=("微软雅黑", 12, "bold"),
bg="#66ccff", fg="white", activebackground="#3399cc",
width=20, height=2, command=change)
start_button.pack(pady=10)
# 滚动留言框
message_var = tk.StringVar()
message_label = tk.Label(root, textvariable=message_var, font=("微软雅黑", 20), fg="#444", bg="#f0faff", wraplength=500, justify="center")
message_label.pack(pady=20)
# 初始数据加载
messages = []
# 初始显示排行榜
leaderboard = load_leaderboard()
update_rank_display(leaderboard)
update_message_display(leaderboard)
scroll_messages()
# 时间标签
timex_label = tk.Label(root, text="点击按钮开始挑战", font=("微软雅黑", 12), bg="#f0faff", fg="#333333")
timex_label.pack(pady=20)
# 按钮
start_button = tk.Button(root, text="🎮 开始 / 停止", font=("微软雅黑", 12, "bold"),
bg="#66ccff", fg="white", activebackground="#3399cc",
width=20, height=2, command=change, relief="raised", bd=3)
start_button.pack(pady=30)
# 控制变量
flag = False
start_time = 0
# 启动主循环
root.mainloop()

View File

@ -1,12 +0,0 @@
[
{
"name": "屈老师",
"error": 0.034,
"message": "我真厉害"
},
{
"name": "sairate",
"error": 0.049,
"message": "我真厉害"
}
]

View File

@ -3,32 +3,35 @@ import json
import os
app = Flask(__name__)
LEADERBOARD_FILE = "leaderboard.json"
LEADERBOARD_FILE = "../leaderboard.json"
# 加载排行榜
# 加载排行榜数据
def load_leaderboard():
if os.path.exists(LEADERBOARD_FILE):
with open(LEADERBOARD_FILE, "r", encoding="utf-8") as f:
return json.load(f)
return []
# 保存排行榜
# 保存排行榜数据
def save_leaderboard(data):
with open(LEADERBOARD_FILE, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
# 获取排行榜
@app.route("/get_board", methods=["GET"])
def get_board():
return jsonify(load_leaderboard())
# 上传排行榜
@app.route("/set_board", methods=["POST"])
def set_board():
try:
data = request.json
save_leaderboard(data)
return jsonify(data)
return jsonify(data) # 直接返回排行榜
except Exception as e:
return jsonify({"status": "error", "message": str(e)}), 400
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000)
app.run(debug=True, port=5000)