feat(第7讲 字母卡牌): 实现记忆游戏并添加开始界面
- 新增 jiyi.py 文件,实现字母翻牌记忆游戏功能 - 添加 youxijiemian.py 文件,创建游戏开始界面 - 使用 turtle 和 tkinter 模块分别实现游戏和界面 - 支持选择不同难度的游戏模式
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
12
.idea/PythonV3_V4.iml
generated
Normal 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>
|
||||
15
.idea/inspectionProfiles/Project_Default.xml
generated
Normal 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>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal 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
@ -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
@ -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
@ -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>
|
||||
BIN
第10讲 识图精灵/50识图精灵讲义.pdf
Normal file
BIN
第10讲 识图精灵/识图精灵.png
Normal file
|
After Width: | Height: | Size: 421 KiB |
5
第10讲 识图精灵/课堂成果/安装第三方库.py
Normal file
@ -0,0 +1,5 @@
|
||||
# 点击运行【安装第三方库.py】,即可安装本课用到的第三方库
|
||||
|
||||
import pip
|
||||
pip.main(['install','baidu-aip'])
|
||||
pip.main(['install','chardet'])
|
||||
BIN
第10讲 识图精灵/课堂成果/花.png
Normal file
|
After Width: | Height: | Size: 102 KiB |
45
第10讲 识图精灵/课堂成果/识图精灵.py
Normal 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('识别完毕')
|
||||
|
||||
BIN
第11讲 语音识别与合成/51语音识别与合成讲义.pdf
Normal file
BIN
第11讲 语音识别与合成/语音识别与合成.png
Normal file
|
After Width: | Height: | Size: 412 KiB |
7
第11讲 语音识别与合成/课堂成果/安装第三方库.py
Normal 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'])
|
||||
48
第11讲 语音识别与合成/课堂成果/录音工具.py
Normal 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")
|
||||
37
第11讲 语音识别与合成/课堂成果/语音合成.py
Normal 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']))
|
||||
36
第11讲 语音识别与合成/课堂成果/语音识别.py
Normal 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)
|
||||
114
第11讲 语音识别与合成/课堂成果/课后作业-柯南变声领带.py
Normal 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']))
|
||||
BIN
第12讲 你的颜值有几分一/52你的颜值有几分一讲义.pdf
Normal file
BIN
第12讲 你的颜值有几分一/你的颜值有几分一.png
Normal file
|
After Width: | Height: | Size: 421 KiB |
114
第12讲 你的颜值有几分一/课堂成果/你的颜值有几分1.py
Normal 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()
|
||||
BIN
第12讲 你的颜值有几分一/课堂成果/测颜值.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
第12讲 你的颜值有几分一/课堂成果/缩略图.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
43
第12讲 你的颜值有几分一/课堂成果/课后作业-本地图片浏览器.py
Normal 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()
|
||||
BIN
第13讲 你的颜值有几分二/53你的颜值有几分二讲义.pdf
Normal file
BIN
第13讲 你的颜值有几分二/你的颜值有几分二.png
Normal file
|
After Width: | Height: | Size: 432 KiB |
154
第13讲 你的颜值有几分二/课堂成果/你的颜值有几分2.py
Normal 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()
|
||||
5
第13讲 你的颜值有几分二/课堂成果/安装第三方库.py
Normal file
@ -0,0 +1,5 @@
|
||||
# 点击运行【安装第三方库.py】,即可安装本课用到的第三方库
|
||||
|
||||
import pip
|
||||
pip.main(['install','baidu-aip'])
|
||||
pip.main(['install','chardet'])
|
||||
BIN
第13讲 你的颜值有几分二/课堂成果/测颜值.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
第13讲 你的颜值有几分二/课堂成果/缩略图.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
157
第13讲 你的颜值有几分二/课堂成果/课堂作业-增加检测项目.py
Normal 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()
|
||||
BIN
第14讲 十秒挑战/54十秒挑战讲义.pdf
Normal file
BIN
第14讲 十秒挑战/十秒挑战.png
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
第14讲 十秒挑战/课堂成果/十秒挑战.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
65
第14讲 十秒挑战/课堂成果/十秒挑战.py
Normal 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()
|
||||
BIN
第14讲 十秒挑战/课堂成果/按钮.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
51
第14讲 十秒挑战/课堂成果/课后作业-点击按钮切换背景颜色.py
Normal 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()
|
||||
BIN
第15讲 星座之谜/55星座之谜讲义.pdf
Normal file
BIN
第15讲 星座之谜/星座之谜.png
Normal file
|
After Width: | Height: | Size: 423 KiB |
BIN
第15讲 星座之谜/课堂成果/星图.gif
Normal file
|
After Width: | Height: | Size: 3.2 MiB |
105
第15讲 星座之谜/课堂成果/星座之谜.py
Normal 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()
|
||||
49
第15讲 星座之谜/课堂成果/生肖计算助手.py
Normal 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()
|
||||
BIN
第16讲 中国地图我来拼(一)/56中国地图我来拼一讲义.pdf
Normal file
BIN
第16讲 中国地图我来拼(一)/中国地图我来拼(一).png
Normal file
|
After Width: | Height: | Size: 422 KiB |
BIN
第16讲 中国地图我来拼(一)/课堂成果/中国地图我来拼.7z
Normal file
64
第16讲 中国地图我来拼(一)/课堂成果/中国地图我来拼1.py
Normal 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()
|
||||
BIN
第17讲 中国地图我来拼(二)/57中国地图我来拼二讲义.pdf
Normal file
BIN
第17讲 中国地图我来拼(二)/中国地图我来拼(二).png
Normal file
|
After Width: | Height: | Size: 417 KiB |
BIN
第17讲 中国地图我来拼(二)/课堂成果/中国地图我来拼.7z
Normal file
69
第17讲 中国地图我来拼(二)/课堂成果/中国地图我来拼2.py
Normal 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()
|
||||
BIN
第18讲 火眼金睛(一)/58火眼金睛一讲义.pdf
Normal file
BIN
第18讲 火眼金睛(一)/火眼金睛(一).png
Normal file
|
After Width: | Height: | Size: 416 KiB |
BIN
第18讲 火眼金睛(一)/课堂成果/火眼金睛.7z
Normal file
48
第18讲 火眼金睛(一)/课堂成果/火眼金睛1.py
Normal 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()
|
||||
39
第18讲 火眼金睛(一)/课堂成果/课后作业-五阶橙色矩阵.py
Normal 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()
|
||||
BIN
第19讲 火眼金睛(二)/59火眼金睛二讲义.pdf
Normal file
BIN
第19讲 火眼金睛(二)/火眼金睛(二).png
Normal file
|
After Width: | Height: | Size: 414 KiB |
BIN
第19讲 火眼金睛(二)/课堂成果/火眼金睛.7z
Normal file
82
第19讲 火眼金睛(二)/课堂成果/火眼金睛.py
Normal 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()
|
||||
89
第19讲 火眼金睛(二)/课堂成果/课后作业-作品优化 .py
Normal 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()
|
||||
BIN
第1讲 点名系统/41点名系统讲义.pdf
Normal file
BIN
第1讲 点名系统/点名系统.png
Normal file
|
After Width: | Height: | Size: 297 KiB |
BIN
第1讲 点名系统/课堂成果/点名.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
40
第1讲 点名系统/课堂成果/点名系统.py
Normal 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()
|
||||
45
第1讲 点名系统/课堂成果/课后作业-晚饭吃什么.py
Normal 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()
|
||||
BIN
第20讲 疯狂的摩托(一)/60疯狂的摩托一讲义.pdf
Normal file
BIN
第20讲 疯狂的摩托(一)/疯狂的摩托(一).png
Normal file
|
After Width: | Height: | Size: 416 KiB |
BIN
第20讲 疯狂的摩托(一)/课堂成果/疯狂的摩托.7z
Normal file
68
第20讲 疯狂的摩托(一)/课堂成果/疯狂的摩托1 .py
Normal 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()
|
||||
48
第20讲 疯狂的摩托(一)/课堂成果/课后作业-小城漫步.py
Normal 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()
|
||||
BIN
第21讲 疯狂的摩托(二)/61疯狂的摩托二讲义.pdf
Normal file
BIN
第21讲 疯狂的摩托(二)/疯狂的摩托(二).png
Normal file
|
After Width: | Height: | Size: 413 KiB |
BIN
第21讲 疯狂的摩托(二)/课堂成果/疯狂的摩托.7z
Normal file
109
第21讲 疯狂的摩托(二)/课堂成果/疯狂的摩托.py
Normal 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()
|
||||
153
第21讲 疯狂的摩托(二)/课堂成果/课后作业 -游戏优化py
Normal 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()
|
||||
BIN
第2讲 弹幕/42弹幕讲义.pdf
Normal file
BIN
第2讲 弹幕/弹幕.png
Normal file
|
After Width: | Height: | Size: 403 KiB |
BIN
第2讲 弹幕/课堂成果/kuang.png
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
BIN
第2讲 弹幕/课堂成果/tv.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
43
第2讲 弹幕/课堂成果/弹幕.py
Normal 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()
|
||||
44
第2讲 弹幕/课堂成果/课后作业.py
Normal 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()
|
||||
BIN
第3讲 二维码生成器/43二维码生成器讲义.pdf
Normal file
BIN
第3讲 二维码生成器/二维码生成器.png
Normal file
|
After Width: | Height: | Size: 412 KiB |
BIN
第3讲 二维码生成器/课堂成果/qrcode_bg.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
38
第3讲 二维码生成器/课堂成果/二维码生成器.py
Normal 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()
|
||||
|
||||
7
第3讲 二维码生成器/课堂成果/安装第三方库.py
Normal file
@ -0,0 +1,7 @@
|
||||
# 点击运行【安装第三方库.py】,即可安装本课用到的第三方库
|
||||
|
||||
import pip
|
||||
pip.main(['install','jieba'])
|
||||
pip.main(['install','wordcloud'])
|
||||
#pip.main(['install','pillow'])
|
||||
#pip.main(['install','numpy'])
|
||||
BIN
第4讲 邮箱轰炸1/44邮箱轰炸1讲义.pdf
Normal file
BIN
第4讲 邮箱轰炸1/课堂成果/email.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
21
第4讲 邮箱轰炸1/课堂成果/课后作业.py
Normal 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)
|
||||
35
第4讲 邮箱轰炸1/课堂成果/邮箱轰炸1.py
Normal 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)
|
||||
BIN
第4讲 邮箱轰炸1/邮箱轰炸1.png
Normal file
|
After Width: | Height: | Size: 407 KiB |
BIN
第5讲 邮箱轰炸2/45邮箱轰炸2讲义.pdf
Normal file
BIN
第5讲 邮箱轰炸2/课堂成果/email.png
Normal file
|
After Width: | Height: | Size: 180 KiB |
73
第5讲 邮箱轰炸2/课堂成果/邮箱轰炸2.py
Normal 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()
|
||||
BIN
第5讲 邮箱轰炸2/邮箱轰炸2.png
Normal file
|
After Width: | Height: | Size: 405 KiB |
BIN
第6讲 太阳系/46太阳系讲义.pdf
Normal file
BIN
第6讲 太阳系/46课太阳系海报.png
Normal file
|
After Width: | Height: | Size: 367 KiB |
BIN
第6讲 太阳系/课堂成果/playground.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
第6讲 太阳系/课堂成果/rabbit.gif
Normal file
|
After Width: | Height: | Size: 1.3 KiB |