重构愚人节疯狂PC程序:如何实现多任务并行运行?
复刻"疯狂PC":多线程实现多功能同时运行
嘿,欢迎回Stack Overflow!很高兴看到你复刻这款经典的愚人节小工具——当年"疯狂PC"可是给不少人带来了无伤大雅的乐趣😉
要让开关光驱、播放音乐、显示图片这些功能同时跑起来,最适合的就是多线程了。因为这些都是IO密集型任务,不需要多核计算,用Python的threading模块就能轻松搞定。下面给你一步步拆解实现思路,再附上完整示例代码:
核心思路:把每个功能拆成独立线程
每个功能写成一个单独的函数,然后用threading.Thread把它们包装成线程,启动后就能同时执行了。另外要加个退出机制,毕竟你说程序要易于关闭。
1. 先准备依赖库
先安装需要的第三方库:
pip install pygame pillow
2. 功能函数实现
光驱循环开关函数
用pygame.cdrom来控制光驱,注意要先初始化CDROM模块:
import time import pygame import threading from PIL import Image, ImageTk import tkinter as tk # 全局退出信号,用来停止所有线程 stop_event = threading.Event() def cdrom_toggle(): # 初始化pygame CDROM模块 pygame.cdrom.init() # 检查是否有光驱 if pygame.cdrom.get_count() == 0: print("没检测到光驱哦") stop_event.set() return cd_drive = pygame.cdrom.CD(0) cd_drive.init() while not stop_event.is_set(): # 弹出光驱 cd_drive.eject() time.sleep(2) # 关闭光驱 cd_drive.close() time.sleep(2) # 清理资源 cd_drive.quit() pygame.cdrom.quit()
循环播放音乐函数
用pygame.mixer来播放音乐,支持MP3、WAV等格式:
def play_music(music_path): pygame.mixer.init() pygame.mixer.music.load(music_path) # 循环播放 pygame.mixer.music.play(-1) while not stop_event.is_set(): time.sleep(1) pygame.mixer.music.stop() pygame.mixer.quit()
弹出图片窗口函数
用Pillow+tkinter来弹出图片窗口,还可以循环切换图片:
def show_images(image_paths): root = tk.Tk() root.attributes("-topmost", True) # 窗口置顶 root.title("疯狂PC来袭!") current_img_idx = 0 img_label = tk.Label(root) img_label.pack() def update_image(): nonlocal current_img_idx if stop_event.is_set(): root.destroy() return # 加载并显示图片 img = Image.open(image_paths[current_img_idx]) # 调整图片大小适配窗口 img = img.resize((400, 300), Image.Resampling.LANCZOS) tk_img = ImageTk.PhotoImage(img) img_label.config(image=tk_img) img_label.image = tk_img # 切换到下一张图片 current_img_idx = (current_img_idx + 1) % len(image_paths) root.after(3000, update_image) # 3秒切换一次 update_image() root.mainloop()
3. 主线程:启动所有功能线程
把上面的函数包装成线程启动,再加个键盘监听来触发退出:
def main(): # 替换成你的音乐和图片路径 MUSIC_PATH = "crazy_music.mp3" IMAGE_PATHS = ["crazy_img1.jpg", "crazy_img2.png", "crazy_img3.gif"] # 创建线程 cd_thread = threading.Thread(target=cdrom_toggle) music_thread = threading.Thread(target=play_music, args=(MUSIC_PATH,)) image_thread = threading.Thread(target=show_images, args=(IMAGE_PATHS,)) # 启动线程 cd_thread.start() music_thread.start() image_thread.start() # 等待用户输入退出指令 print("程序已启动,按回车键退出!") input() # 设置退出信号,让所有线程停止 stop_event.set() # 等待所有线程结束 cd_thread.join() music_thread.join() image_thread.join() print("程序已关闭") if __name__ == "__main__": main()
一些注意事项
- 权限问题:Windows系统下控制光驱可能需要管理员权限,运行程序时右键选择"以管理员身份运行"。
- 路径问题:确保音乐和图片的路径是正确的,用绝对路径更稳妥。
- 自定义调整:可以修改线程里的
time.sleep时长,调整光驱开关速度、图片切换间隔;也可以加更多图片或者换搞怪的音乐。
内容的提问来源于stack exchange,提问作者That One
相关产品推荐
相关产品推荐

