You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重构愚人节疯狂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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:40:00