feat(第7讲 字母卡牌): 实现记忆游戏并添加开始界面

- 新增 jiyi.py 文件,实现字母翻牌记忆游戏功能
- 添加 youxijiemian.py 文件,创建游戏开始界面
- 使用 turtle 和 tkinter 模块分别实现游戏和界面
- 支持选择不同难度的游戏模式
This commit is contained in:
sairate 2025-06-28 14:27:31 +08:00
commit c4d32e8092
168 changed files with 2713 additions and 0 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,3 @@
# 默认忽略的文件
/shelf/
/workspace.xml

12
.idea/PythonV3_V4.iml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

View File

@ -0,0 +1,15 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="2">
<item index="0" class="java.lang.String" itemvalue="numpy" />
<item index="1" class="java.lang.String" itemvalue="pyzero" />
</list>
</value>
</option>
</inspection_tool>
</profile>
</component>

View File

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

12
.idea/material_theme_project_new.xml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="21c1c7ee:193388d497c:-7ff9" />
</MTProjectMetadataState>
</option>
</component>
</project>

4
.idea/misc.xml generated Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/PythonV3_V4.iml" filepath="$PROJECT_DIR$/.idea/PythonV3_V4.iml" />
</modules>
</component>
</project>

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

View File

@ -0,0 +1,5 @@
# 点击运行【安装第三方库.py】即可安装本课用到的第三方库
import pip
pip.main(['install','baidu-aip'])
pip.main(['install','chardet'])

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -0,0 +1,45 @@
"""
运行前必做
1. 运行安装第三方库.py文件
2. 注册百度云账号获取API配置后查看完整效果
账号注册指南
https://huewq7h021.feishu.cn/wiki/Ry3UwaoceiMRXgklbWtc9mEUn9f?from=from_copylink
"""
from aip import AipImageClassify # 调用百度智能模块中图像识别类方法
# 填写个人的授权使用信息
APP_ID = '你的 AppID'
API_KEY = '你的 API Key'
SECRET_KEY = '你的 Secret Key'
# 准备【图像识别器】
client = AipImageClassify(APP_ID, API_KEY, SECRET_KEY)
# 读取图片文件并返回二进制数据
def read_img(file):
with open(file, "rb") as f:
return f.read()
# 调用【图像识别器】并返回结果
def find_img(img):
# 返回的信息是字典类型结果保存在键result的值中
return client.advancedGeneral(img)
# 打印识别结果
def print_result(res):
if 'result' in res:
for i in res['result']:
if i['score'] >= 0.6:
print(f"结果为 {i['keyword']} , 相似度为 {i['score']*100:.2f}% ")
else:
# 失败响应提示信息
print(f"识别失败, 错误码: {res.get('error_code')}, 错误信息: {res.get('error_msg')}")
# 主函数
data = read_img("花.png")
result = find_img(data)
print(f"API返回结果{result}\n")
print_result(result)
print('识别完毕')

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

View File

@ -0,0 +1,7 @@
# 点击运行【安装第三方库.py】即可安装本课用到的第三方库
import pip
pip.main(['install','pyaudio'])
pip.main(['install','keyboard'])
pip.main(['install','baidu-aip'])
pip.main(['install','chardet'])

View File

@ -0,0 +1,48 @@
# 按下's'开始录制,按下'q'停止录制,文件存为'pyaudio.wav'
import pyaudio
import wave
import keyboard
# 从麦克风录制音频并保存到指定文件
# 创建 PyAudio 对象
p = pyaudio.PyAudio()
# 打开音频流,设置格式、声道数、采样率等参数
stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024)
# 创建一个空列表用于存储录制的音频数据
frames = []
# 打印提示信息,表示开始录制
print("Press 's' to start recording...")
# 等待用户按下 's' 键开始录制
keyboard.wait('s')
# 打印提示信息,表示开始录制
print("Recording...")
# 开始录制
while True:
# 从音频流中读取 1024 个数据样本
data = stream.read(1024)
# 将数据添加到 frames 列表中
frames.append(data)
# 检查是否按下 'q' 键结束录制
if keyboard.is_pressed('q'):
break
# 打印提示信息,表示录制已停止
print("Recording stopped.")
# 停止音频流
stream.stop_stream()
# 关闭音频流
stream.close()
# 终止 PyAudio 对象
p.terminate()
# 打开文件,以写入模式打开
wf = wave.open("pyaudio.wav", 'wb')
# 设置音频的声道数、采样宽度和采样率
wf.setnchannels(1)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(16000)
# 将 frames 列表中的所有数据连接成一个字节串,并写入文件
wf.writeframes(b''.join(frames))
# 关闭文件
wf.close()
print("Done")

View File

@ -0,0 +1,37 @@
"""
运行前必做
1. 运行安装第三方库.py文件
2. 注册百度云账号获取API配置后查看完整效果
账号注册指南
https://huewq7h021.feishu.cn/wiki/Ry3UwaoceiMRXgklbWtc9mEUn9f?from=from_copylink
"""
from aip import AipSpeech
# 定义常量
APP_ID = '你的 AppID'
API_KEY = '你的 API Key'
SECRET_KEY = '你的 Secret Key'
# 准备【语音合成器】
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
# 要合成的文本
text = "你好我是P仔很高兴认识你"
# 调用【语音合成器】
res = client.synthesis(text, 'zh', 1, {
'vol': 5, # 音量
'per': 0, # 发音人
'spd': 5 # 语速
})
print(res)
# 判断调用是否成功
if not isinstance(res, dict):
# 获取合成音频结果
with open('save.mp3', 'wb') as f:
f.write(res)
print('音频文件保存成功')
else:
print('调用失败, 错误码: %s, 错误信息: %s' % (res['err_no'], res['err_msg']))

View File

@ -0,0 +1,36 @@
"""
运行前必做
1. 运行安装第三方库.py文件
2. 注册百度云账号获取API配置后查看完整效果
账号注册指南
https://huewq7h021.feishu.cn/wiki/Ry3UwaoceiMRXgklbWtc9mEUn9f?from=from_copylink
"""
from aip import AipSpeech
# 定义常量
APP_ID = '你的 AppID'
API_KEY = '你的 API Key'
SECRET_KEY = '你的 Secret Key'
# 准备【语音识别器】
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
# 定义要识别的语音文件
file = 'pyaudio.wav'
# 读取音频文件
def read_audio(file):
with open(file, 'rb') as f:
return f.read()
# 调用【语音识别器】
res = client.asr(read_audio(file), 'wav', 16000, {
'dev_pid': 1537 # 普通话识别
})
# 打印返回结果
if 'result' in res:
print("识别结果:", res['result'][0])
else:
print("识别失败:", res)

View File

@ -0,0 +1,114 @@
"""
运行前必做
1. 运行安装第三方库.py文件
2. 注册百度云账号获取API配置后查看完整效果
账号注册指南
https://huewq7h021.feishu.cn/wiki/Ry3UwaoceiMRXgklbWtc9mEUn9f?from=from_copylink
"""
'''柯南变声领结
任务描述
变身名侦探柯南制作一个神奇的变声领结你将录制一段音频通过语音识别转换成文字再通过语音合成器将文字变成机器人音调快来挑战吧看谁的变声音效最酷
作业要求
1. 将课堂代码语音识别语音合成整合到一个文件中
2. 文字合成语音选择喜欢的语音人'''
import pyaudio
import wave
import keyboard
from aip import AipSpeech
# 从麦克风录制音频并保存到指定文件
# 创建 PyAudio 对象
p = pyaudio.PyAudio()
# 打开音频流,设置格式、声道数、采样率等参数
stream = p.open(format=pyaudio.paInt16, channels=1, rate=16000, input=True, frames_per_buffer=1024)
# 创建一个空列表用于存储录制的音频数据
frames = []
# 打印提示信息,表示开始录制
print("Press 's' to start recording...")
# 等待用户按下 's' 键开始录制
keyboard.wait('s')
# 打印提示信息,表示开始录制
print("Recording...")
# 开始录制
while True:
# 从音频流中读取 1024 个数据样本
data = stream.read(1024)
# 将数据添加到 frames 列表中
frames.append(data)
# 检查是否按下 'q' 键结束录制
if keyboard.is_pressed('q'):
break
# 打印提示信息,表示录制已停止
print("Recording stopped.")
# 停止音频流
stream.stop_stream()
# 关闭音频流
stream.close()
# 终止 PyAudio 对象
p.terminate()
# 打开文件,以写入模式打开
wf = wave.open("pyaudio.wav", 'wb')
# 设置音频的声道数、采样宽度和采样率
wf.setnchannels(1)
wf.setsampwidth(p.get_sample_size(pyaudio.paInt16))
wf.setframerate(16000)
# 将 frames 列表中的所有数据连接成一个字节串,并写入文件
wf.writeframes(b''.join(frames))
# 关闭文件
wf.close()
print("Done")
# 定义常量
APP_ID = '你的 AppID'
API_KEY = '你的 API Key'
SECRET_KEY = '你的 Secret Key'
# 准备【语音工具】
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
# 定义要识别的语音文件
file = 'pyaudio.wav'
# 读取音频文件
def read_audio(file):
with open(file, 'rb') as f:
return f.read()
# 调用语音识别接口
res = client.asr(read_audio(file), 'wav', 16000, {
'dev_pid': 1537 # 普通话识别
})
# 打印返回结果
if 'result' in res:
print("识别结果:", res['result'][0])
else:
print("识别失败:", res)
# 要合成的文本
text = res['result'][0]
# 调用语音合成接口
res = client.synthesis(text, 'zh', 1, {
'vol': 5, # 音量
'per': 0, # 发音人
'spd': 5 # 语速
})
print(res)
# 判断调用是否成功
if not isinstance(res, dict):
# 获取合成音频结果
with open('save.mp3', 'wb') as f:
f.write(res)
print('音频文件保存成功')
else:
print('调用失败, 错误码: %s, 错误信息: %s' % (res['err_no'], res['err_msg']))

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

View File

@ -0,0 +1,114 @@
'''
导入库
'''
# 预置内容,请勿改动
import io
import base64
import cv2
# 请在下方编写代码
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog
'''
初始化变量初始化窗口初始化API配置信息
'''
# 预置内容,请勿改动
cap = None
imgtk = None
update_id = None
# 请在下方编写代码
# 初始化Tkinter
root = tk.Tk()
root.geometry('700x700')
root.title('颜值测评')
root.resizable(0, 0)
'''
函数
'''
# 预置内容,请勿改动 图像 --> 字节数据 --> Base64 编码格式
def img_to_bytes(photoimg):
# 将 PhotoImage 转换为 PIL 图像
pil_img = ImageTk.getimage(photoimg)
# 如果图像具有 Alpha 信道(透明度),则转换为 RGB
if pil_img.mode == 'RGBA':
pil_img = pil_img.convert('RGB')
# 保存到字节缓冲区
buffer = io.BytesIO()
pil_img.save(buffer, format='JPEG')
img_data = buffer.getvalue()
return base64.b64encode(img_data).decode('utf-8')
# 预置内容,请勿改动 打开摄像头
def open_camera():
global cap, update_id
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("无法打开摄像头")
return
def update_frame():
global cap, update_id
ret, frame = cap.read()
if frame is None:
return
frame = cv2.resize(frame, (250, 250))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame)
imgtk = ImageTk.PhotoImage(img)
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
update_id = lab_photo.after(10, update_frame)
update_frame()
# 预置内容,请勿改动 关闭摄像头
def close_camera():
global cap, update_id
if cap is not None:
cap.release()
cap = None
if update_id is not None:
lab_photo.after_cancel(update_id)
update_id = None
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
# 请在下方编写代码
# 加载本地图片
def load():
file_path = filedialog.askopenfilename() # 打开一个文件选择对话框
if file_path:
close_camera()
img = Image.open(file_path)
img = img.resize((250, 250))
imgtk = ImageTk.PhotoImage(img)
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
# 颜值检测开始
def ok():
pass
'''
组件配置
'''
# 设置背景图
bg_image = tk.PhotoImage(file = '测颜值.png')
bg_label = tk.Label(root, image = bg_image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)
# 设置缩略图
pic0 = Image.open('缩略图.png')
pic0 = pic0.resize((250, 250))
pic0_image = ImageTk.PhotoImage(pic0)
lab_photo = tk.Label(root, image=pic0_image)
lab_photo.place(x=223, y=223)
# 本地上传按钮
btn_load = tk.Button(root, text="本地上传", command=load, width=15, height=2, font=("楷体", 12))
btn_load.place(x=115, y=625)
# 拍照上传按钮
btn_cam = tk.Button(root, text="拍照上传", command=open_camera, width=15, height=2, font=("楷体", 12))
btn_cam.place(x=300, y=625)
# 开始测评按钮
btn_enter = tk.Button(root, text="点击开测!", command=ok, width=15, height=2, font=("楷体", 12))
btn_enter.place(x=485, y=625)
'''
启动事件循环
'''
root.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,43 @@
'''本地图片浏览器
任务描述
创建一个简单的图片浏览器用户可以从计算机中选择一张图片并在窗口中指定位置显示
作业要求
1. 界面包括选择按钮和一个图片显示区域300*300
2. 加载本地图片使用文件对话框让用户选择一张本地图片
3. 图片缩放选中的图片进行缩放来匹配显示区域
4. 更新显示选择新图片后界面应更新所选图片'''
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog
def load():
file_path = filedialog.askopenfilename()
if file_path:
img = Image.open(file_path)
img = img.resize((300, 300)) # 缩放图片
imgtk = ImageTk.PhotoImage(img)
label.config(image=imgtk)
label.image = imgtk
root = tk.Tk()
root.title("本地图片浏览器")
root.geometry("350x350")
# 显示图片区域
label = tk.Label(root)
label.pack()
# 按钮用于选择图片
button = tk.Button(root, text="选择图片", command=load)
button.pack()
root.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 432 KiB

View File

@ -0,0 +1,154 @@
"""
运行前必做
1. 运行安装第三方库.py文件
2. 注册百度云账号获取API配置后查看完整效果
账号注册指南
https://huewq7h021.feishu.cn/wiki/Ry3UwaoceiMRXgklbWtc9mEUn9f?from=from_copylink
"""
'''
导入库
'''
# 预置内容,请勿改动
import io
import base64
import cv2
# 请在下方编写代码
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog, messagebox
from aip import AipFace
'''
初始化变量初始化窗口初始化API配置信息
'''
# 预置内容,请勿改动
cap = None
imgtk = None
update_id = None
# 请在下方编写代码
# 初始化Tkinter
root = tk.Tk()
root.geometry('700x700')
root.title('颜值测评')
root.resizable(0, 0)
# 百度AI的API配置信息
APP_ID = '你的 AppID'
API_KEY = '你的 API Key'
SECRET_KEY = '你的 Secret Key'
client = AipFace(APP_ID, API_KEY, SECRET_KEY)
'''
函数
'''
# 预置内容,请勿改动 图像 --> 字节数据 --> Base64 编码格式
def img_to_bytes(photoimg):
# 将 PhotoImage 转换为 PIL 图像
pil_img = ImageTk.getimage(photoimg)
# 如果图像具有 Alpha 信道(透明度),则转换为 RGB
if pil_img.mode == 'RGBA':
pil_img = pil_img.convert('RGB')
# 保存到字节缓冲区
buffer = io.BytesIO()
pil_img.save(buffer, format='JPEG')
img_data = buffer.getvalue()
return base64.b64encode(img_data).decode('utf-8')
# 预置内容,请勿改动 打开摄像头
def open_camera():
global cap, update_id
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("无法打开摄像头")
return
def update_frame():
global cap, update_id
ret, frame = cap.read()
if frame is None:
return
frame = cv2.resize(frame, (250, 250))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame)
imgtk = ImageTk.PhotoImage(img)
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
update_id = lab_photo.after(10, update_frame)
update_frame()
# 预置内容,请勿改动 关闭摄像头
def close_camera():
global cap, update_id
if cap is not None:
cap.release()
cap = None
if update_id is not None:
lab_photo.after_cancel(update_id)
update_id = None
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
# 请在下方编写代码
# 加载本地图片
def load():
file_path = filedialog.askopenfilename() # 打开一个文件选择对话框
if file_path:
close_camera()
img = Image.open(file_path)
img = img.resize((250, 250))
imgtk = ImageTk.PhotoImage(img)
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
# 颜值检测开始
def ok():
# 判断 lab_photo 对象是否具有属性 imgtk
if not hasattr(lab_photo, 'imgtk'):
messagebox.showerror("错误", "没有显示图片,无法进行颜值测试")
return
img_base64 = img_to_bytes(lab_photo.imgtk) # 将图片转为Base64
imageType = "BASE64" # 设置图片类型
options = {"face_field":"age,gender,face_shape,emotion,beauty"}
result = client.detect(img_base64, imageType, options)
if 'error_msg' in result and result['error_msg'] == 'pic not has face':
messagebox.showerror("错误", "图像中未检测到人脸")
return
if 'result' in result and 'face_list' in result['result']:
# 解析结果
age = result['result']['face_list'][0]['age']
gender = result['result']['face_list'][0]['gender']['type']
face_shape = result['result']['face_list'][0]['face_shape']['type']
emotion = result['result']['face_list'][0]['emotion']['type']
beauty = result['result']['face_list'][0]['beauty']
# 构造结果字符串
output_str=f"年龄:{age}\n性别:{gender}\n脸型:{face_shape}\n情绪:{emotion}\n颜值:{beauty}"
# 使用对话框显示结果
messagebox.showinfo("颜值测评结果", output_str)
else:
messagebox.showerror("错误", "检测失败,请重试")
'''
组件配置
'''
# 设置背景图
bg_image = tk.PhotoImage(file = '测颜值.png')
bg_label = tk.Label(root, image = bg_image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)
# 设置缩略图
pic0 = Image.open('缩略图.png')
pic0 = pic0.resize((250, 250))
pic0_image = ImageTk.PhotoImage(pic0)
lab_photo = tk.Label(root, image=pic0_image)
lab_photo.place(x=223, y=223)
# 本地上传按钮
btn_load = tk.Button(root, text="本地上传", command=load, width=15, height=2, font=("楷体", 12))
btn_load.place(x=115, y=625)
# 拍照上传按钮
btn_cam = tk.Button(root, text="拍照上传", command=open_camera, width=15, height=2, font=("楷体", 12))
btn_cam.place(x=300, y=625)
# 开始测评按钮
btn_enter = tk.Button(root, text="点击开测!", command=ok, width=15, height=2, font=("楷体", 12))
btn_enter.place(x=485, y=625)
'''
启动事件循环
'''
root.mainloop()

View File

@ -0,0 +1,5 @@
# 点击运行【安装第三方库.py】即可安装本课用到的第三方库
import pip
pip.main(['install','baidu-aip'])
pip.main(['install','chardet'])

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,157 @@
"""
运行前必做
1. 运行安装第三方库.py文件
2. 注册百度云账号获取API配置后查看完整效果
账号注册指南
https://huewq7h021.feishu.cn/wiki/Ry3UwaoceiMRXgklbWtc9mEUn9f?from=from_copylink
"""
'''
导入库
'''
# 【预置内容,请勿改动】
import io
import base64
import cv2
# 请在下方编写代码
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import filedialog, messagebox
from aip import AipFace
'''
初始化变量初始化窗口初始化API配置信息
'''
# 【预置内容,请勿改动】
cap = None
imgtk = None
update_id = None
# 请在下方编写代码
# 初始化Tkinter
root = tk.Tk()
root.geometry('700x700')
root.title('颜值测评')
root.resizable(0, 0)
# 百度AI的API配置信息
APP_ID = '你的 AppID'
API_KEY = '你的 API Key'
SECRET_KEY = '你的 Secret Key'
client = AipFace(APP_ID, API_KEY, SECRET_KEY)
'''
函数
'''
# 【预置内容,请勿改动】 图像 --> 字节数据 --> Base64 编码格式
def img_to_bytes(photoimg):
# 将 PhotoImage 转换为 PIL 图像
pil_img = ImageTk.getimage(photoimg)
# 如果图像具有 Alpha 信道(透明度),则转换为 RGB
if pil_img.mode == 'RGBA':
pil_img = pil_img.convert('RGB')
# 保存到字节缓冲区
buffer = io.BytesIO()
pil_img.save(buffer, format='JPEG')
img_data = buffer.getvalue()
return base64.b64encode(img_data).decode('utf-8')
# 【预置内容,请勿改动】打开摄像头
def open_camera():
global cap, update_id
cap = cv2.VideoCapture(0)
if not cap.isOpened():
print("无法打开摄像头")
return
def update_frame():
global cap, update_id
ret, frame = cap.read()
if frame is None:
return
frame = cv2.resize(frame, (250, 250))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame)
imgtk = ImageTk.PhotoImage(img)
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
update_id = lab_photo.after(10, update_frame)
update_frame()
# 【预置内容,请勿改动】关闭摄像头
def close_camera():
global cap, update_id
if cap is not None:
cap.release()
cap = None
if update_id is not None:
lab_photo.after_cancel(update_id)
update_id = None
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
# 请在下方编写代码
# 加载本地图片
def load():
file_path = filedialog.askopenfilename() # 打开一个文件选择对话框
if file_path:
close_camera()
img = Image.open(file_path)
img = img.resize((250, 250))
imgtk = ImageTk.PhotoImage(img)
lab_photo.imgtk = imgtk
lab_photo.config(image=imgtk)
# 颜值检测开始
def ok():
# 判断 lab_photo 对象是否具有属性 imgtk
if not hasattr(lab_photo, 'imgtk'):
messagebox.showerror("错误", "没有显示图片,无法进行颜值测试")
return
img_base64 = img_to_bytes(lab_photo.imgtk) # 将图片转为Base64
imageType = "BASE64" # 设置图片类型
options = {"face_field":"age,gender,face_shape,emotion,beauty,glasses,mask,face_type"}
result = client.detect(img_base64, imageType, options)
if 'error_msg' in result and result['error_msg'] == 'pic not has face':
messagebox.showerror("错误", "图像中未检测到人脸")
return
if 'result' in result and 'face_list' in result['result']:
# 解析结果
age = result['result']['face_list'][0]['age']
gender = result['result']['face_list'][0]['gender']['type']
face_shape = result['result']['face_list'][0]['face_shape']['type']
emotion = result['result']['face_list'][0]['emotion']['type']
beauty = result['result']['face_list'][0]['beauty']
glasses = result['result']['face_list'][0]['glasses']['type']
mask = result['result']['face_list'][0]['mask']['type']
face_type = result['result']['face_list'][0]['face_type']['type']
# 构造结果字符串
result_str1=f"年龄:{age}\n性别:{gender}\n脸型:{face_shape}\n情绪:{emotion}\n颜值:{beauty}\n"
result_str2=f"是否戴眼镜:{glasses}\n是否戴口罩:{mask}\n人脸类型:{face_type}"
# 使用对话框显示结果
messagebox.showinfo("颜值测评结果", result_str1+result_str2)
else:
messagebox.showerror("错误", "检测失败,请重试")
'''
组件配置
'''
# 设置背景图
bg_image = tk.PhotoImage(file = '测颜值.png')
bg_label = tk.Label(root, image = bg_image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)
# 设置缩略图
pic0 = Image.open('缩略图.png')
pic0 = pic0.resize((250, 250))
pic0_image = ImageTk.PhotoImage(pic0)
lab_photo = tk.Label(root, image=pic0_image)
lab_photo.place(x=223, y=223)
# 本地上传按钮
btn_load = tk.Button(root, text="本地上传", command=load, width=15, height=2, font=("楷体", 12))
btn_load.place(x=115, y=625)
# 拍照上传按钮
btn_cam = tk.Button(root, text="拍照上传", command=open_camera, width=15, height=2, font=("楷体", 12))
btn_cam.place(x=300, y=625)
# 开始测评按钮
btn_enter = tk.Button(root, text="点击开测!", command=ok, width=15, height=2, font=("楷体", 12))
btn_enter.place(x=485, y=625)
'''
启动事件循环
'''
root.mainloop()

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

View File

@ -0,0 +1,65 @@
import tkinter as tk
import time
from tkinter import messagebox
# 创建主窗口
root = tk.Tk()
root.geometry("300x400") # 设置窗口大小
root.title("10秒挑战")
bg_image = tk.PhotoImage(file = '十秒挑战.png')
bg_label = tk.Label(root, image = bg_image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)
# 初始化运行状态
flag = False
# 定期更新显示时间
def update_time():
if flag:
now = time.time()
timex = now - start_time
timex_label.config(text=f"时间:{timex:.3f}\n")
root.after(10, update_time) # 10ms 后更新一次
# 根据当前状态开始或停止计时
def change():
global flag, start_time
if not flag: # 如果计时尚未开始
flag = True
start_time = time.time() # 获取当前时间戳
update_time() # 开始更新时间显示
else: # 如果计时已经开始
flag = False # 停止更新时间显示
end_time = time.time() # 获取当前时间戳
timex = end_time - start_time # 计算实际耗时
goal = 10 # 目标耗时
# 计算时间差
time_difference = timex - goal
# 更新显示
timex_label.config(text=f"实际时间:{timex:.3f}\n误差:{time_difference:.3f}")
# 显示结果
if f'{time_difference:.3f}' == '0.000':
messagebox.showinfo("结果","难以置信!你就是掌控时间的神!")
else:
messagebox.showinfo("结果","还差一点点,再接再厉吧!")
# 创建标签
title_label = tk.Label(root, text="10 秒挑战", font=("楷体", 16))
title_label.pack(pady=(72,10))
# 创建时间显示标签
timex_label = tk.Label(root, text="点击按钮开始挑战\n", font=("楷体", 12))
timex_label.pack(pady=(22,17))
# 创建按钮并设置图片
btn_photo = tk.PhotoImage(file = '按钮.png')
btn = tk.Button(root, image=btn_photo, command=change)
btn.pack(pady=20)
# 运行Tkinter主循环
root.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,51 @@
'''【课后作业】
点击切换背景颜色
要求
1.窗口内有标签按钮如图所示
2.窗口初始背景为蓝色
3.蓝色背景时点击按钮背景变红弹出对话框变红了红色背景时点击按钮背景变蓝弹出对话框变蓝了
注意窗口名.config(bg='颜色')
可以设置更改窗口背景颜色'''
import tkinter as tk
from tkinter import messagebox
# 初始化主窗口
root = tk.Tk()
root.geometry("300x200+600+300")
root.title("背景颜色切换")
# 初始化背景颜色标记
is_blue = True
def change():
global is_blue
if is_blue:
root.config(bg="red")
is_blue = False
messagebox.showinfo("提示", "变红了")
else:
root.config(bg="blue")
is_blue = True
messagebox.showinfo("提示", "变蓝了")
# 创建标签提示操作
label = tk.Label(root, text="点击按钮切换背景颜色", font=("楷体", 14))
label.pack(pady=20)
# 创建按钮来切换背景颜色
change_button = tk.Button(root, text="切换背景颜色", command=change)
change_button.pack(pady=10)
# 初始化背景颜色为蓝色
root.config(bg="blue")
# 运行Tkinter主循环
root.mainloop()

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

View File

@ -0,0 +1,105 @@
import tkinter as tk
from PIL import Image, ImageTk
from tkinter import messagebox
# 预置内容,请勿改动
def check(month, day): # 判断星座的函数
if (month == 1 and day >= 20) or (month == 2 and day <= 18):
return "水瓶座♒"
elif (month == 2 and day >= 19) or (month == 3 and day <= 20):
return "双鱼座♓"
elif (month == 3 and day >= 21) or (month == 4 and day <= 19):
return "白羊座♈"
elif (month == 4 and day >= 20) or (month == 5 and day <= 20):
return "金牛座♉"
elif (month == 5 and day >= 21) or (month == 6 and day <= 21):
return "双子座♊"
elif (month == 6 and day >= 22) or (month == 7 and day <= 22):
return "巨蟹座♋"
elif (month == 7 and day >= 23) or (month == 8 and day <= 22):
return "狮子座♌"
elif (month == 8 and day >= 23) or (month == 9 and day <= 22):
return "处女座♍"
elif (month == 9 and day >= 23) or (month == 10 and day <= 23):
return "天秤座♎"
elif (month == 10 and day >= 24) or (month == 11 and day <= 22):
return "天蝎座♏"
elif (month == 11 and day >= 23) or (month == 12 and day <= 21):
return "射手座♐"
elif (month == 12 and day >= 22) or (month == 1 and day <= 19):
return "摩羯座♑"
# 创建Tkinter窗口
root = tk.Tk()
root.geometry('320x360')
root.title("测测你的星座吧")
# 创建一个标签用于显示gif动画
label_bg = tk.Label(root)
label_bg.place(x=0, y=0, relwidth=1, relheight=1) #将标签放在窗口顶部并充斥整个窗口
# 加载gif图片并将每一帧存储在frames列表中
image = Image.open('星图.gif') # 打开gif图片文件
frames = [] # 用于存储gif的所有帧
try:
while True:
frames.append(ImageTk.PhotoImage(image)) # 将每一帧添加到frames列表中
image.seek(len(frames)) # 跳转到gif的下一帧
except EOFError:
pass # 当到达gif结束时跳出循环
# 用于更新gif动画帧的函数
def upd(idx):
frame = frames[idx] # 获取当前帧
label_bg.configure(image=frame) # 更新标签中显示的帧
idx = (idx + 1) % len(frames) # 计算下一帧的索引
root.after(100, upd, idx) # 100毫秒后调用自己继续更新帧
upd(0) # 开始播放gif动画
# 创建标签和文本框
label_year = tk.Label(root, text="出生年:")
label_year.grid(row=0, column=0, padx=(60,10), pady=(140,10))
entry_year = tk.Entry(root)
entry_year.grid(row=0, column=1, pady=(140,10))
label_month = tk.Label(root, text="出生月:")
label_month.grid(row=1, column=0, padx=(60,10), pady=10)
entry_month = tk.Entry(root)
entry_month.grid(row=1, column=1, pady=10)
label_day = tk.Label(root, text="出生日:")
label_day.grid(row=2, column=0, padx=(60,10), pady=10)
entry_day = tk.Entry(root)
entry_day.grid(row=2, column=1, pady=10)
# 按钮点击处理函数
# 点击提交按钮时调用,它获取用户输入的出生年月日,验证输入有效性,并显示对应的星座信息
def click():
year = entry_year.get() # 获取用户输入的出生年份
month = entry_month.get() # 获取用户输入的出生月份
day = entry_day.get() # 获取用户输入的出生日
# 检查用户输入的年、月、日是否为有效的数字
if not year.isdigit() or not month.isdigit() or not day.isdigit():
messagebox.showerror("输入错误", "请输入有效的日期")
month = int(month) # 将月份转换为整数
day = int(day) # 将日期转换为整数
# 检查日期是否在有效范围内
if month < 1 or month > 12 or day < 1 or day > 31:
messagebox.showerror("输入错误", "请输入有效的日期")
result = check(month, day) # 调用check函数获取星座信息
messagebox.showinfo("星座", f"你的星座是:{result}") # 显示用户的星座信息
# 创建提交按钮
btn = tk.Button(root, text="提交", command=click)
btn.grid(row=3, columnspan=2, padx=(80,10), pady=10)
# 运行Tkinter主循环
root.mainloop()

View File

@ -0,0 +1,49 @@
'''【课后作业要求】
生肖计算助手
要求
1.窗口内有标签单行文本输入框提交按钮
2.输入正确的年份1900-2100后会弹出对话框显示生肖
3.输入的年份不在范围内或者不是数字格式会弹出错误对话框
注意判断生肖的函数check(year)已经预置好可以直接调用组件的位置可以自行调整合理美观即可'''
import tkinter as tk
from tkinter import messagebox
root = tk.Tk()
root.geometry("300x200+600+300")
root.title("生肖计算助手")
# 预置内容,请勿改动
def check(year):
sx = ["", "", "", "", "", "", "", "", "", "", "", ""]
idx = (year - 1900) % 12
return sx[idx]
def click():
year = entry_year.get()
if not year.isdigit():
messagebox.showerror("输入错误", "请输入有效的年份数值")
year = int(year)
if year < 1900 or year > 2100:
messagebox.showerror("输入错误", "请输入有效的年份数值")
result = check(year)
messagebox.showinfo("属相", f"您的生肖是:{result}")
label_year = tk.Label(root, text='出生年份:')
label_year.grid(row=0, column=0, padx=20, pady=50)
entry_year = tk.Entry(root)
entry_year.grid(row=0, column=1, pady=50)
btn = tk.Button(root, text='提交', command=click)
btn.grid(row=1, columnspan=2, padx=(60, 0))
root.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

View File

@ -0,0 +1,64 @@
# 预置内容,请勿改动
a = {"01新疆碎片": (225, 231), "02西藏碎片": (244, 457), "03内蒙古碎片": (623, 203),
"04青海碎片": (383, 396), "05四川碎片": (491, 521), "06黑龙江碎片": (861, 122),
"07甘肃碎片": (472, 358), "08云南碎片": (457, 621), "09广西碎片": (580, 656),
"10湖南碎片": (640, 584), "11陕西碎片": (586, 415), "12河北碎片": (718, 330),
"13吉林碎片": (859, 228), "14湖北碎片": (654, 506), "15广东碎片": (678, 677),
"16贵州碎片": (549, 593), "17河南碎片": (672, 446), "18江西碎片": (724, 584),
"19山东碎片": (758, 392), "20山西碎片": (650, 369), "21辽宁碎片": (805, 284),
"22安徽碎片": (740, 487), "23福建碎片": (766, 609), "24江苏碎片": (770, 462),
"25浙江碎片": (793, 538), "26重庆碎片": (573, 525), "27宁夏碎片": (548, 375),
"28台湾碎片": (824, 652), "29海南碎片": (610, 753), "30北京碎片": (715, 310),
"31天津碎片": (730, 326), "32上海碎片": (818, 495)} # 省份文件名称和对应的正确位置
# 导入库
import pgzrun
import os
import random
# 设置窗口
WIDTH = 1000 # 窗口的宽度
HEIGHT = 800 # 窗口的高度
# 设置窗口标题
TITLE = '中国地图我来拼'
# 初始值设置
selected_piece = None # 当前被选择的碎片
selected_name = None # 当前被选择的碎片名字
# 加载碎片
pieces = []
# 遍历指定文件夹中的所有文件
for filename in os.listdir('images'):
if filename[-6:] == '碎片.png': # 只处理以碎片.png结尾的文件
img = Actor(filename[:-4], (random.randint(0, WIDTH), random.randint(0, HEIGHT)))
pieces.append([img, filename[:-4], False]) # 添加所有碎片和碎片信息到列表
# 刷新屏幕
def draw():
screen.blit('中国地图背景',(0,0)) # 绘制背景
# 绘制每个碎片
for piece in pieces:
piece[0].draw()
# 鼠标按下事件
def on_mouse_down(pos):
global selected_piece, selected_name
for piece, name, placed in pieces:
if piece.collidepoint(pos) and not placed: # 检查是否点击到未正确放置的碎片
selected_piece = piece # 记录选择的碎片
selected_name = name # 记录碎片名称
break
# 鼠标移动事件
def on_mouse_move(pos):
if selected_piece != None and 0<pos[0]<1000 and 0<pos[1]<800: # 如果有选中碎片且鼠标未移出窗口,就随着鼠标移动
selected_piece.pos = pos # 更新选中碎片的位置
# 鼠标释放事件
def on_mouse_up(pos):
# <检测碎片是否正确放置>
pass
# 启动游戏
pgzrun.go()

Binary file not shown.

After

Width:  |  Height:  |  Size: 417 KiB

View File

@ -0,0 +1,69 @@
# 预置内容,请勿改动
a = {"01新疆碎片": (225, 231), "02西藏碎片": (244, 457), "03内蒙古碎片": (623, 203),
"04青海碎片": (383, 396), "05四川碎片": (491, 521), "06黑龙江碎片": (861, 122),
"07甘肃碎片": (472, 358), "08云南碎片": (457, 621), "09广西碎片": (580, 656),
"10湖南碎片": (640, 584), "11陕西碎片": (586, 415), "12河北碎片": (718, 330),
"13吉林碎片": (859, 228), "14湖北碎片": (654, 506), "15广东碎片": (678, 677),
"16贵州碎片": (549, 593), "17河南碎片": (672, 446), "18江西碎片": (724, 584),
"19山东碎片": (758, 392), "20山西碎片": (650, 369), "21辽宁碎片": (805, 284),
"22安徽碎片": (740, 487), "23福建碎片": (766, 609), "24江苏碎片": (770, 462),
"25浙江碎片": (793, 538), "26重庆碎片": (573, 525), "27宁夏碎片": (548, 375),
"28台湾碎片": (824, 652), "29海南碎片": (610, 753), "30北京碎片": (715, 310),
"31天津碎片": (730, 326), "32上海碎片": (818, 495)} # 省份文件名称和对应的正确位置
# 导入库
import pgzrun
import os
import random
# 设置窗口
WIDTH = 1000 # 窗口的宽度
HEIGHT = 800 # 窗口的高度
# 设置窗口标题
TITLE = '中国地图我来拼'
# 初始值设置
selected_piece = None # 当前被选择的碎片
selected_name = None # 当前被选择的碎片名字
# 加载碎片
pieces = []
# 遍历指定文件夹中的所有文件
for filename in os.listdir('images'):
if filename[-6:] == '碎片.png': # 只处理以碎片.png结尾的文件
img = Actor(filename[:-4], (random.randint(0, WIDTH), random.randint(0, HEIGHT)))
pieces.append([img, filename[:-4], False]) # 添加所有碎片和碎片信息到列表
# 刷新屏幕
def draw():
screen.blit('中国地图背景', (0, 0)) # 绘制背景
# 绘制每个碎片
for piece in pieces:
piece[0].draw()
# 鼠标按下事件
def on_mouse_down(pos):
global selected_piece, selected_name
for piece, name, placed in pieces:
if piece.collidepoint(pos) and not placed: # 检查是否点击到未正确放置的碎片
selected_piece = piece # 记录选择的碎片
selected_name = name # 记录碎片名称
break
# 鼠标移动事件
def on_mouse_move(pos):
if selected_piece != None and 0 < pos[0] < 1000 and 0 < pos[1] < 800: # 如果有选中碎片且鼠标未移出窗口,就随着鼠标移动
selected_piece.pos = pos # 更新选中碎片的位置
# 鼠标释放事件
def on_mouse_up(pos):
# <检测碎片是否正确放置>
pass
# 启动游戏
pgzrun.go()

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

View File

@ -0,0 +1,48 @@
import pgzrun
import random
# 设置窗口
WIDTH = 1000 # 窗口的宽度
HEIGHT = 725 # 窗口的高度
def draw():
screen.blit('火眼金睛.png', (0, 0))
for grid in grids:
screen.draw.filled_rect(Rect(grid['pos'], (side, side)), 'white')
def update():
pass
def base_color():
"""生成随机基础颜色"""
return (random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255))
def dif_color(base):
"""
参数
base表示基础颜色的元组格式为r,g,b
"""
r = min(base[0] + random.randint(20, 30), 255)
g = min(base[1] + random.randint(20, 30), 255)
b = min(base[2] + random.randint(20, 30), 255)
return (r, g, b)
# 初始为3×3的矩阵
n = 3
# 根据格子数量计算格子边长和间距
side = 700 // n * 0.9
space = 700 // n * 0.1
# 创建列表grids后面存储每个方格信息
grids = []
for row in range(n): # 遍历行
for col in range(n): # 遍历列
info = {
'pos': (space + col * (side + space), space + row * (side + space)),
'color': 'white' # 测试用,后续及时更新对应颜色 
}
grids.append(info)
# 启动游戏
pgzrun.go()

View File

@ -0,0 +1,39 @@
'''
五阶橙色矩阵
要求如下
1. 方块边长为40间距为5
2. 绘制五阶矩阵方块
3. 方块为橙色orange'''
# 导入pgzero库
import pgzrun
# 设置窗口
WIDTH = 725 # 窗口的宽度
HEIGHT = 725 # 窗口的高度
def draw():
for grid in grids:
screen.draw.filled_rect(Rect(grid['pos'], (side, side)), 'orange')
# 五阶矩阵
n = 5
# 提供边长和间距
side = 40
space = 5
# 创建列表grids后面存储每个方格信息
grids = []
for row in range(n): # 遍历行
for col in range(n): # 遍历列
info = {
'pos': (space + col * (side + space), space + row * (side + space)),
}
grids.append(info)
# 启动游戏
pgzrun.go()

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

View File

@ -0,0 +1,82 @@
import pgzrun
import random
import time
WIDTH = 1000 # 窗口的宽度
HEIGHT = 725 # 窗口的高度
def draw():
screen.blit('火眼金睛.png', (0, 0))
if win:
screen.blit('游戏成功.png', (0, 0))
screen.draw.text(f"{total_t:.1f}", center=(520, 570), fontsize=90, color="yellow")
else:
screen.draw.text(f"{t:.1f} s", center=(900, 662), fontsize=40, color="yellow")
for grid in grids:
screen.draw.filled_rect(Rect(grid['pos'], (side, side)), grid['color'])
def update():
"""更新函数,用于实时更新游戏状态相关信息,这里主要更新总耗时"""
global t
t = time.time() - start_t
def base_color():
"""生成随机基础颜色"""
return (random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255))
def dif_color(base):
"""
参数
base表示基础颜色的元组格式为r,g,b
"""
r = min(base[0] + random.randint(20, 30), 255)
g = min(base[1] + random.randint(20, 30), 255)
b = min(base[2] + random.randint(20, 30), 255)
return (r, g, b)
def game():
global grids, side, dc
# 根据格子数量计算格子边长和间距
side = 700 // n * 0.9
space = 700 // n * 0.1
# 创建列表grids后面存储每个方格信息
grids = []
# 获取基础色和异色
bc = base_color()
dc = dif_color(bc)
# 记录方格编号
i = 1
# 随机选择一个位置的方格设置略微不同的颜色
dif_index = random.randint(1, n * n)
for row in range(n):
for col in range(n):
info = {
'pos': (space + col * (side + space),
space + row * (side + space)),
'color': dc if i == dif_index else bc
}
grids.append(info)
i += 1
def on_mouse_down(pos):
global n, win, total_t
for grid in grids:
grid_rect = Rect(grid['pos'], (side, side))
if grid_rect.collidepoint(pos) and grid['color'] == dc:
if n > 10:
win = True
total_t = t
else:
n += 1 # 进入下一关
game()
# 初始化游戏参数
n = 3 # 初始为3×3的矩阵
win = False # 记录游戏成功状态
start_t = time.time() # 记录开始时间
game()
# 启动游戏
pgzrun.go()

View File

@ -0,0 +1,89 @@
'''作品优化 —— 增大游戏难度
提示
1. 增加关卡数量
2. 减小基础色和异色的区别'''
import pgzrun
import random
import time
WIDTH = 1000 # 窗口的宽度
HEIGHT = 725 # 窗口的高度
def draw():
screen.blit('火眼金睛.png', (0, 0))
if win:
screen.blit('游戏成功.png', (0, 0))
screen.draw.text(f"{total_t:.1f}", center=(520, 570), fontsize=90, color="yellow")
else:
screen.draw.text(f"{t:.1f} s", center=(900, 662), fontsize=40, color="yellow")
for grid in grids:
screen.draw.filled_rect(Rect(grid['pos'], (side, side)), grid['color'])
def update():
"""更新函数,用于实时更新游戏状态相关信息,这里主要更新总耗时"""
global t
t = time.time() - start_t
def base_color():
"""生成随机基础颜色"""
return (random.randint(0, 255),
random.randint(0, 255),
random.randint(0, 255))
def dif_color(base):
"""
参数
base表示基础颜色的元组格式为r,g,b
"""
r = min(base[0] + random.randint(20, 25), 255)
g = min(base[1] + random.randint(20, 25), 255)
b = min(base[2] + random.randint(20, 25), 255)
return (r, g, b)
def game():
global grids, side, dc
# 根据格子数量计算格子边长和间距
side = 700 // n * 0.9
space = 700 // n * 0.1
# 创建列表grids后面存储每个方格信息
grids = []
# 获取基础色和异色
bc = base_color()
dc = dif_color(bc)
# 记录方格编号
i = 1
# 随机选择一个位置的方格设置略微不同的颜色
dif_index = random.randint(1, n * n)
for row in range(n):
for col in range(n):
info = {
'pos': (space + col * (side + space),
space + row * (side + space)),
'color': dc if i == dif_index else bc
}
grids.append(info)
i += 1
def on_mouse_down(pos):
global n, win, total_t
for grid in grids:
grid_rect = Rect(grid['pos'], (side, side))
if grid_rect.collidepoint(pos) and grid['color'] == dc:
if n > 20:
win = True
total_t = t
else:
n += 1 # 进入下一关
game()
# 初始化游戏参数
n = 3 # 初始为3×3的矩阵
win = False # 记录游戏成功状态
start_t = time.time() # 记录开始时间
game()
# 启动游戏
pgzrun.go()

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 297 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@ -0,0 +1,40 @@
# 导入所需要的库
from tkinter import *
import random
# 创建主窗口
root = Tk()
root.geometry('500x150+300+500')
root.title('点名系统')
bg_image = PhotoImage(file = '点名.png')
bg_label = Label(root, image = bg_image)
bg_label.place(x=0, y=0, relwidth=1, relheight=1)
# 设置全局变量
var = StringVar() # 这个变量用来显示在标签上的名字
names = ['小明', '红红', '粘豆包', '牛牛'] # 这个列表存储学生的名字
flag = False # 这个标志用来表示是否正在进行点名
# 定义一个函数,用来进行点名
def roll():
if flag: # 如果正在进行点名,那么显示一个随机的名字
var.set(random.choice(names))
root.after(10, roll) # 在10毫秒后再次调用这个函数
# 定义一个函数,用来切换点名状态
def check():
global flag # 声明我们要使用的是全局变量,而不是创建一个新的局部变量
if flag: # 如果正在进行点名,那么停止点名
flag = False
else: # 否则,开始点名
flag = True
roll()
# 创建并配置标签和按钮
Label(root, textvariable=var, font=('楷体', 50)).pack()
Button(root, text="开始/停止点名", command=check).pack()
# 启动事件循环
root.mainloop()

View File

@ -0,0 +1,45 @@
'''【课后作业要求】
晚饭吃什么
要求
1. 点击按钮食物开始滚动
2. 再次点击按钮食物停止滚动显示晚饭要吃的食物
3. 修改合适的题目和按钮文本'''
# 导入所需要的库
from tkinter import *
import random
# 创建主窗口
root = Tk()
root.geometry('300x100+300+500')
root.title('晚饭吃什么')
# 设置全局变量
var = StringVar()
foods = ['火锅', '烤肉', '炒菜', '烧烤']
rolling = False
# 定义一个函数,用来滚动清单
def roll_food():
if rolling:
var.set(random.choice(foods))
root.after(10, roll_food)
# 定义一个函数,用来切换按钮状态
def toggle_roll():
global rolling
if rolling:
rolling = False
else:
rolling = True
roll_food()
# 创建并配置标签和按钮
Label(root, textvariable=var, font=('楷体', 40)).pack()
Button(root, text="开始/停止滚动", command=toggle_roll).pack()
# 启动事件循环
root.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

View File

@ -0,0 +1,68 @@
import pgzrun
import random
from pgzhelper import *
# 游戏窗口大小
WIDTH = 1500
HEIGHT = 800
# 创建背景角色
bg1 = Actor('连续道路', topleft = (0,0))
bg2 = Actor('连续道路', topleft = (1500,0))
# 创建障碍物
obstacles = []
for _ in range(3): # 障碍物数量
x = random.randint(WIDTH, WIDTH + 1500) # 障碍物出现在屏幕右侧外
y = random.randint(100, HEIGHT - 50)
obstacles.append(Actor('路障', (x, y)))
# 创建摩托车
motor = Actor('摩托1', (200, HEIGHT // 2))
# 将摩托造型存放在列表内
motor.images = ['摩托1','摩托2']
# 初始化设置
speed = 15
def draw():
# 绘制连续背景
bg1.draw()
bg2.draw()
# 绘制障碍物
for obs in obstacles:
obs.draw()
# 绘制摩托
motor.draw()
# 背景、终点线移动
def bg_move():
bg1.x -= speed
bg2.x -= speed
if bg1.right <= 0:
bg1.left = bg2.right
if bg2.right <= 0:
bg2.left = bg1.right
# 更新障碍物位置
def obs_move():
for obs in obstacles:
obs.x -= speed # 障碍物随背景一起移动
if obs.x < 0:
obs.x = random.randint(WIDTH, WIDTH + 1500) # 障碍物继续出现在屏幕外
obs.y = random.randint(100, HEIGHT - 50)
def update():
bg_move()
obs_move()
# 控制赛车移动,限制不能出界
if keyboard.up and motor.top > 0:
motor.y -= 7
if keyboard.down and motor.bottom < HEIGHT-50:
motor.y += 7
def change_image():
motor.next_image()
clock.schedule_interval(change_image,0.2)
pgzrun.go()

View File

@ -0,0 +1,48 @@
'''小城漫步
要求如下
1. 白日街景夜晚街景两图滚动出现
2. 走1走2两图实现博克斯走路动效
3. 按下键盘右键背景滚动'''
import pgzrun
from pgzhelper import *
WIDTH = 960
HEIGHT = 720
# 创建背景角色
bg1 = Actor('白日街景', topleft=(0, 0))
bg2 = Actor('夜晚街景', topleft=(960, 0))
# 创建博克斯角色
people = Actor('走1', (200, 500))
people.images = ['走1', '走2']
# 初始化速度
speed = 10
def draw():
bg1.draw()
bg2.draw()
people.draw()
def update():
if keyboard.right:
bg1.x -= speed
bg2.x -= speed
if bg1.right <= 0:
bg1.left = bg2.right
if bg2.right <= 0:
bg2.left = bg1.right
def change_image():
people.next_image()
clock.schedule_interval(change_image, 0.5)
pgzrun.go()

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 KiB

View File

@ -0,0 +1,109 @@
import pgzrun
import random
from pgzhelper import *
# 游戏窗口大小
WIDTH = 1500
HEIGHT = 800
# 创建背景角色
bg1 = Actor('连续道路', topleft = (0,0))
bg2 = Actor('连续道路', topleft = (1500,0))
# 创建障碍物
obstacles = []
for _ in range(3): # 障碍物数量
x = random.randint(WIDTH, WIDTH + 1500) # 障碍物出现在屏幕右侧外
y = random.randint(100, HEIGHT - 50)
obstacles.append(Actor('路障', (x, y)))
# 创建摩托车
motor = Actor('摩托1', (200, HEIGHT // 2))
# 将摩托造型存放在列表内
motor.images = ['摩托1','摩托2']
# 创建终点线
line = Actor('终点线', topleft = (20000, 163))
# 初始化设置
speed = 15
flag = 0
def draw():
# 绘制连续背景
bg1.draw()
bg2.draw()
if flag == 1:
music.stop()
screen.blit('摩托成功', (0,0))
elif flag == 2:
music.stop()
screen.blit('摩托失败', (0,0))
else:
# 绘制障碍物
for obs in obstacles:
obs.draw()
# 绘制摩托
motor.draw()
# 绘制终点线
line.draw()
# 绘制距离文字
x = int(line.x-motor.x)
screen.draw.text(f'距终点:{x} m', (50,700), fontname = 'simkai', fontsize = 50)
# 背景、终点线移动
def bg_move():
bg1.x -= speed
bg2.x -= speed
if bg1.right <= 0:
bg1.left = bg2.right
if bg2.right <= 0:
bg2.left = bg1.right
line.x -= speed
# 更新障碍物位置
def obs_move():
for obs in obstacles:
obs.x -= speed # 障碍物随背景一起移动
if obs.x < 0:
obs.x = random.randint(WIDTH, WIDTH + 1500) # 障碍物继续出现在屏幕外
obs.y = random.randint(100, HEIGHT - 50)
# 最后冲刺
def line_collide():
global flag
if motor.collide_pixel(line):
flag = 1
sounds.胜利.play()
else:
motor.x += 15
# 判断是否与障碍物相撞
def obs_collide():
global flag
for obs in obstacles:
if motor.collide_pixel(obs):
flag = 2
sounds.失败.play()
def update():
if flag == 0:
if line.x > WIDTH - 200: # 正常行驶
bg_move()
obs_move()
else: # 最后冲刺
line_collide()
# 控制赛车移动,限制不能出界
if keyboard.up and motor.top > 0:
motor.y -= 7
if keyboard.down and motor.bottom < HEIGHT-50:
motor.y += 7
# 是否碰撞障碍物
obs_collide()
def change_image():
motor.next_image()
clock.schedule_interval(change_image,0.2)
music.play('速度与激情')
pgzrun.go()

View File

@ -0,0 +1,153 @@
'''游戏优化
要求如下:
1. 绘制‘钻石’角色
2. 钻石随背景同步移动,移出舞台后从右侧重新进入
3. 摩托碰到钻石后,钻石从右侧重新进入
4. 变量 score 记录收集到的钻石数量
5. 在窗口内,绘制文字‘收集宝石:×颗’'''
import pgzrun
import random
from pgzhelper import *
# 游戏窗口大小
WIDTH = 1500
HEIGHT = 800
# 创建背景角色
bg1 = Actor('连续道路', topleft=(0, 0))
bg2 = Actor('连续道路', topleft=(1500, 0))
# 创建障碍物
obstacles = []
for _ in range(3): # 障碍物数量
x = random.randint(WIDTH, WIDTH + 1500) # 障碍物出现在屏幕右侧外
y = random.randint(100, HEIGHT - 50)
obstacles.append(Actor('路障', (x, y)))
# 创建摩托车
motor = Actor('摩托1', (200, HEIGHT // 2))
# 将摩托造型存放在列表内
motor.images = ['摩托1', '摩托2']
# 创建终点线
line = Actor('终点线', topleft=(20000, 163))
# 创建钻石
zuan = Actor('钻石', topleft=(WIDTH + 100, random.randint(100, HEIGHT - 50)))
# 初始化设置
speed = 15
flag = 0
score = 0
def draw():
# 绘制连续背景
bg1.draw()
bg2.draw()
if flag == 1:
music.stop()
screen.blit('摩托成功', (0, 0))
elif flag == 2:
music.stop()
screen.blit('摩托失败', (0, 0))
else:
# 绘制障碍物
for obs in obstacles:
obs.draw()
# 绘制摩托
motor.draw()
# 绘制终点线
line.draw()
# 绘制钻石
zuan.draw()
# 绘制距离文字
x = int(line.x - motor.x)
screen.draw.text(f'距终点:{x} m', (50, 700), fontname='simkai', fontsize=50)
# 绘制钻石数量文字
screen.draw.text(f'收集钻石:{score}颗', (50, 100), fontname='simkai', fontsize=50)
# 背景、终点线移动
def bg_move():
bg1.x -= speed
bg2.x -= speed
if bg1.right <= 0:
bg1.left = bg2.right
if bg2.right <= 0:
bg2.left = bg1.right
line.x -= speed
zuan.x -= speed
if zuan.x <= 0:
zuan.x = random.randint(WIDTH, WIDTH + 1500)
zuan.y = random.randint(100, HEIGHT - 50)
# 更新障碍物位置
def obs_move():
for obs in obstacles:
obs.x -= speed # 障碍物随背景一起移动
if obs.x < 0:
obs.x = random.randint(WIDTH, WIDTH + 1500) # 障碍物继续出现在屏幕外
obs.y = random.randint(100, HEIGHT - 50)
# 最后冲刺
def line_collide():
global flag
if motor.collide_pixel(line):
flag = 1
else:
motor.x += 15
# 判断是否与障碍物相撞
def obs_collide():
global flag
for obs in obstacles:
if motor.collide_pixel(obs):
flag = 2
# 收集钻石
def zuan_collide():
global score
if motor.collide_pixel(zuan):
score += 1
zuan.x = random.randint(WIDTH, WIDTH + 1500)
zuan.y = random.randint(100, HEIGHT - 50)
def update():
if flag == 0:
if line.x > WIDTH - 200: # 正常行驶
bg_move()
obs_move()
else: # 最后冲刺
line_collide()
# 控制赛车移动,限制不能出界
if keyboard.up and motor.top > 0:
motor.y -= 7
if keyboard.down and motor.bottom < HEIGHT - 50:
motor.y += 7
# 是否碰撞障碍物
obs_collide()
# 是否碰到钻石
zuan_collide()
def change_image():
motor.next_image()
clock.schedule_interval(change_image, 0.2)
music.play('速度与激情')
pgzrun.go()

Binary file not shown.

BIN
第2讲 弹幕/弹幕.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,43 @@
import tkinter as tk
import random
import threading
import time
from PIL import Image, ImageTk
class MovingLabel(threading.Thread):
def __init__(self, window, text):
threading.Thread.__init__(self)
self.text = text
self.label = tk.Label(window, image=kuang,text=self.text, compound="center",font=("黑体",20),fg='white',width=190,height=45)
self.label.place(x=800, y=random.randint(50, 400))
def run(self):
x = 800
while x > -200:
x -= 2
self.label.place(x=x)
time.sleep(0.02)
self.label.destroy()
def send():
text = e1.get()
ml = MovingLabel(window, text)
ml.start()
window = tk.Tk()
window.geometry('1000x670')
window.resizable(0,0)
kuang = ImageTk.PhotoImage(file='kuang.png')
bg_image = Image.open("tv.png")
bg_image = ImageTk.PhotoImage(bg_image)
bg_label = tk.Label(window, image=bg_image)
bg_label.pack()
e1=tk.Entry(window, font=("黑体", 20))
e1.place(x=280,y=620)
b1=tk.Button(window, text="发送弹幕", font=("黑体", 20), command=send)
b1.place(x=580,y=613)
window.mainloop()

View File

@ -0,0 +1,44 @@
import tkinter as tk
import random
import threading
import time
from PIL import Image, ImageTk
class MovingLabel(threading.Thread):
def __init__(self, window, text):
threading.Thread.__init__(self)
self.text = text
self.label = tk.Label(window, image=kuang,text=self.text, compound="center",font=("黑体",20),fg='white',width=190,height=45)
#self.label.place(x=800, y=random.randint(10, 550))
self.label.place(x=random.randint(10, 550), y=300)
def run(self):
y = 500
while y > 0:
y -= 2
self.label.place(y=y)
time.sleep(0.02)
self.label.destroy()
def send():
text = e1.get()
ml = MovingLabel(window, text)
ml.start()
window = tk.Tk()
window.geometry('1000x670')
window.resizable(0,0)
kuang = ImageTk.PhotoImage(file='kuang.png')
bg_image = Image.open("tv.png")
bg_image = ImageTk.PhotoImage(bg_image)
bg_label = tk.Label(window, image=bg_image)
bg_label.pack()
e1=tk.Entry(window, font=("黑体", 20))
e1.place(x=280,y=620)
b1=tk.Button(window, text="发送弹幕", font=("黑体", 20), command=send)
b1.place(x=580,y=613)
window.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 412 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,38 @@
# 编程前,运行【安装第三方库.py】文件安装本课用到的第三方库
import tkinter
from PIL import Image, ImageTk
from tkinter import filedialog
import os
from amzqr import amzqr
w = tkinter.Tk()
w.geometry("400x400")
w.resizable(0,0)
bg_image = Image.open("qrcode_bg.png")
bg_image = ImageTk.PhotoImage(bg_image)
bg_label = tkinter.Label(w, image=bg_image)
bg_label.pack()
t1 = tkinter.Text(w, font=("微软雅黑", 12),width=30,height=5)
t1.place(x=80, y=100)
t2 = tkinter.Text(w, font=("微软雅黑", 12),width=23,height=1)
t2.place(x=80, y=250)
def get_pic():
pic_path = filedialog.askopenfilename()
t2.delete("1.0", "end")
t2.insert("1.0", pic_path)
btn1 = tkinter.Button(w, text="浏览", font=("微软雅黑", 12), command=get_pic)
btn1.place(x=312, y=250, height=25)
def qr():
words = t1.get("1.0","end")
words = "".join(words.split('\n'))
picture = t2.get("1.0", "end")[:-1]
version, level, qr_name = amzqr.run(words=words, picture=picture, colorized=True)
os.system(qr_name)
btn2 = tkinter.Button(w, text="生成二维码", font=("微软雅黑", 15), command=qr)
btn2.place(x=80, y=300, width=250)
w.mainloop()

View File

@ -0,0 +1,7 @@
# 点击运行【安装第三方库.py】即可安装本课用到的第三方库
import pip
pip.main(['install','jieba'])
pip.main(['install','wordcloud'])
#pip.main(['install','pillow'])
#pip.main(['install','numpy'])

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -0,0 +1,21 @@
import smtplib
from email.mime.text import MIMEText
from email.utils import formataddr
import time
to=input("输入收件人:")
count=int(input("发送次数:"))
user='zhangsan444444z@163.com'
password='FMORERKAQJWEBSUX'
subject = "新年祝福"
content = "新年快乐,祝您新年大吉!"
msg = MIMEText(content,'html','utf-8')
msg['Subject'] = subject
msg['From'] = formataddr(('张三',user))
msg['to'] = to
s = smtplib.SMTP_SSL("smtp.163.com", 465)
s.login(user, password)
for i in range(count):
s.sendmail(user, to, msg.as_string())
print('成功')
time.sleep(2)

View File

@ -0,0 +1,35 @@
# 1 导入模块
import smtplib
from email.mime.text import MIMEText #往邮件中写内容的对象
from email.utils import formataddr #发件人信息
import time
# 2 发送方和接收方配置
# 发件方邮箱:谁发送的
user='zhangsan444444z@163.com'
# 生成的授权码:不能泄露
password='FMORERKAQJWEBSUX'
# # 发送给谁,可以写多个人,以列表形式存储
to="zhangsan444444z@163.com"
subject = "新年祝福" # 邮件主题
content = "新年快乐,祝您新年大吉!" # 邮箱内容
# 生成一个MIMEText对象发送html格式邮件
msg = MIMEText(content,'html','utf-8')
# 放入邮件主题
msg['Subject'] = subject
# 放入发件人,元祖中内容第一个是发件人名称,第二个是发件地址
msg['From'] = formataddr(('张三',user))
# 放入收件人,将收件人转化为以逗号分隔的字符串
msg['to'] = to
# 通过ssl方式发送服务器地址端口 465 994
s = smtplib.SMTP_SSL("smtp.163.com", 465)
# 登录到邮箱
s.login(user, password)
# 发送邮件:发送方,收件方,要发送的消息
for i in range(5):
s.sendmail(user, to, msg.as_string()) # 第二个参数可以以列表的方式写多个
print('成功')
time.sleep(2)

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

View File

@ -0,0 +1,73 @@
# 1 导入模块
import smtplib
from email.mime.text import MIMEText #往邮件中写内容的对象
from email.utils import formataddr #发件人信息
import time
import tkinter
import threading
# 2 发送方和接收方配置
# 发件方邮箱:谁发送的
user='zhangsan444444z@163.com'
# 生成的授权码:不能泄露
password='FMORERKAQJWEBSUX'
def send_mail():
to = e1.get()
content = t2.get("1.0", "end")
count = int(e3.get())
delay= int(e4.get())
subject = "To:{}".format(to) # 邮件主题
#content = "新年快乐,祝您新年大吉!" # 邮箱内容
# 生成一个MIMEText对象发送html格式邮件
msg = MIMEText(content,'html','utf-8')
# 放入邮件主题
msg['Subject'] = subject
# 放入发件人,元祖中内容第一个是发件人名称,第二个是发件地址
msg['From'] = formataddr(('张三',user))
# 放入收件人,将收件人转化为以逗号分隔的字符串
msg['to'] = to
# 通过ssl方式发送服务器地址端口 465 994
s = smtplib.SMTP_SSL("smtp.163.com", 465)
# 登录到邮箱
s.login(user, password)
# 发送邮件:发送方,收件方,要发送的消息
for i in range(count):
s.sendmail(user, to, msg.as_string()) # 第二个参数可以以列表的方式写多个
print('成功')
time.sleep(delay)
def send():
t = threading.Thread(target=send_mail)
t.start()
w = tkinter.Tk()
w.geometry('800x600')
w.resizable(0,0)
bg = tkinter.PhotoImage(file='email.png')
bg_label = tkinter.Label(w, image=bg)
bg_label.place(x=0, y=0)
e1 = tkinter.Entry(w,font=("黑体",20),width=18)
e1.place(x=150, y=190)
t2 = tkinter.Text(w,font=("黑体",20),width=18,height=8)
t2.place(x=150, y=255)
e3 = tkinter.Entry(w,font=("黑体",20),width=8)
e3.place(x=508, y=190)
e4 = tkinter.Entry(w,font=("黑体",20),width=8)
e4.place(x=508, y=322)
b5 = tkinter.Button(w, text="发送", font=("黑体",20),width=8,command=send)
b5.place(x=508,y=425)
w.mainloop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Some files were not shown because too many files have changed in this diff Show More