如何通过Python在macOS Monterey中关闭屏幕保护程序
Python媒体播放器Mac端禁用屏幕保护失效问题
我开发了一款Python媒体播放器,希望在视频播放期间关闭屏幕保护程序。Windows端功能正常,但Mac端始终无法实现。用caffeine模块的代码在PyCharm里能正常运行,但编译成程序后就会崩溃。其他尝试的代码片段也都没效果,求排查明显错误。
相关代码
import sys import ctypes def turn_screen_saver_off(): if sys.platform == "win32": print("turn_screen_saver_off") ctypes.windll.kernel32.SetThreadExecutionState(0x80000002) elif sys.platform == "darwin": print("turn_screen_saver_off") #import caffeine #caffeine.on(display=True) #subprocess.run(['caffeinate', '-s']) # Keep the system awake #from AppKit import NSBundle #bundle = NSBundle.mainBundle() #info = bundle.localizedInfoDictionary() or bundle.infoDictionary() #info['NSScreensaverDisabled'] = True #script = 'tell application "System Events" to set sleep to 0' #os.system(f"osascript -e '{script}'") def turn_screen_saver_on(): if sys.platform == "win32": print("turn_screen_saver_on") ctypes.windll.kernel32.SetThreadExecutionState(0x80000000) elif sys.platform == "darwin": print("turn_screen_saver_on") #import caffeine #caffeine.off() #subprocess.run(['killall', 'caffeinate']) # Allow the system to sleep ##from AppKit import NSBundle #bundle = NSBundle.mainBundle() #info = bundle.localizedInfoDictionary() or bundle.infoDictionary() #info['NSScreensaverDisabled'] = True #script = 'tell application "System Events" to set sleep to 1' #os.system(f"osascript -e '{script}'")
尝试过的无效代码片段
#import caffeine #caffeine.on(display=True) #subprocess.run(['caffeinate', '-s']) # Keep the system awake #from AppKit import NSBundle #bundle = NSBundle.mainBundle() #info = bundle.localizedInfoDictionary() or bundle.infoDictionary() #info['NSScreensaverDisabled'] = True #script = 'tell application "System Events" to set sleep to 0' #os.system(f"osascript -e '{script}'")
问题排查与修正方案
1. 各尝试方案的核心错误
- caffeine模块编译崩溃:打包过程中未正确包含caffeine依赖,或该模块在打包环境下存在兼容性问题,底层调用Mac API时触发异常。
- subprocess.run调用caffeinate:
run方法会阻塞等待进程结束,导致代码卡住;且后续用killall会误杀其他程序启动的caffeinate进程。 - NSBundle修改NSScreensaverDisabled:该配置属于程序启动前的Info.plist设置,运行时修改完全无效。
- osascript脚本错误:
set sleep to 0是无效命令,System Events中没有该语法,且编译后的程序可能缺少辅助功能权限。
2. 修正后的可用代码
import sys import ctypes import subprocess # 保存caffeinate进程实例,用于后续终止 caffeinate_proc = None def turn_screen_saver_off(): if sys.platform == "win32": print("turn_screen_saver_off") # 防止屏幕休眠与屏保启动 ctypes.windll.kernel32.SetThreadExecutionState(0x80000002) elif sys.platform == "darwin": print("turn_screen_saver_off") # 启动后台caffeinate进程,-s参数保持屏幕唤醒 global caffeinate_proc caffeinate_proc = subprocess.Popen(['caffeinate', '-s']) # 可选:用AppleScript禁用屏保(需辅助功能权限) # import os # script = ''' # tell application "System Events" # set screen saver enabled to false # end tell # ''' # os.system(f"osascript -e '{script}'") def turn_screen_saver_on(): if sys.platform == "win32": print("turn_screen_saver_on") # 恢复系统默认状态 ctypes.windll.kernel32.SetThreadExecutionState(0x80000000) elif sys.platform == "darwin": print("turn_screen_saver_on") # 终止自身启动的caffeinate进程 global caffeinate_proc if caffeinate_proc: caffeinate_proc.terminate() caffeinate_proc.wait() # 可选:恢复屏保 # import os # script = ''' # tell application "System Events" # set screen saver enabled to true # end tell # ''' # os.system(f"osascript -e '{script}'")
3. 额外注意事项
- 用
caffeinate命令的方式无需第三方依赖,打包更稳定,且不需要额外系统权限。 - 若选择AppleScript方案,需在「系统设置-隐私与安全性-辅助功能」中给编译后的程序添加权限,否则脚本执行会失败。
- 打包时(如用PyInstaller),若仍想用caffeine模块,需添加参数
--hidden-import=caffeine确保依赖被包含。
内容的提问来源于stack exchange,提问作者mrrockkz
相关产品推荐
相关产品推荐

