实现PPT演示的"非全屏播放"效果

本文介绍了一种在PowerPoint中实现非全屏播放幻灯片的方法,通过简单的键盘快捷键即可实现,并且可以在播放时轻松切换到其他程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载者: 动态ppt模板下载 免费              来源: www.2ppt.cn

  在实际使用PowerPoint的演示文稿过程中,往往需要与其它程序窗口的数据配合使用以增强演示的效果,但是如果用鼠标点击 PowerPoint幻灯片放映菜单中的“观看幻灯片”选项,或者直接按下“F5”快捷键,将启动默认的全屏放映模式。在这种模式下则必须使用 “Alt+Tab”或“Alt+Esc”组合键与其它窗口切换,很不方便。

  其实,我们只要这样操作,就可以得到一个带标题栏和菜单栏的PowerPoint幻灯片“非全屏”播放窗口了。

  先按住Alt键不圆柱的体积ppt课件放,再依次按下D、V键激活PowerPoint中幻灯片播放。这样我们就可以在PowerPoint幻灯片播放时也能对播放窗口进行操作了,如最小化和自定义大小等。

  如果需要返回PowerPoint的编辑状态,请按住Alt键不放,再按两下E键,则可返回设计编辑模式,编辑PowerPoint文档了。

本文选自 http://www.2ppt.cn/Article/1006.html
import os import time import win32com.client import win32gui import win32con from pythoncom import CoInitialize, CoUninitialize # 显式导入COM函数 import threading import psutil import pyautogui from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.keys import Keys from selenium.webdriver.common.action_chains import ActionChains # 移除独立的日志配置,使用 app.py 的日志系统 class PPTController: """控制PPT全屏播放和翻页""" _is_active = False # 类属性,标记是否有活跃的PPT _is_ready = False # 类属性,标记PPT是否已经准备好(即已经全屏并开始放映) _presentation = None # 当前打开的演示文稿对象 _application = None # PowerPoint应用程序对象 _lock = threading.Lock() # 添加线程锁 _logger = None # 日志记录器 _com_initialized = False # 标记COM是否已初始化 @classmethod def set_logger(cls, logger): """设置日志记录器""" cls._logger = logger @classmethod def open_fullscreen(cls, ppt_path): """打开PPT全屏播放(新增循环播放功能)""" # 如果已经有打开的PPT,先关闭 if cls._is_active: cls.close() try: with cls._lock: # 使用线程锁确保线程安全 # 初始化 COM try: CoInitialize() cls._com_initialized = True if cls._logger: cls._logger.debug("COM初始化成功") except Exception as e: if cls._logger: cls._logger.error(f"COM初始化失败: {str(e)}") return False, f"COM初始化失败: {str(e)}" # 检查文件是否存在 if not os.path.exists(ppt_path): if cls._logger: cls._logger.error(f"PPT文件不存在: {ppt_path}") # 清理COM资源 cls._safe_uninitialize() return False, "PPT文件不存在" # 尝试使用PowerPoint,如果失败则尝试WPS try: cls._application = win32com.client.Dispatch("PowerPoint.Application") if cls._logger: cls._logger.info("使用Microsoft PowerPoint打开文件") is_powerpoint = True # 标记是否为PowerPoint except Exception as e: if cls._logger: cls._logger.warning(f"无法启动PowerPoint, 尝试WPS: {str(e)}") try: cls._application = win32com.client.Dispatch("KWPP.Application") if cls._logger: cls._logger.info("使用WPS演示打开文件") is_powerpoint = False # 标记为WPS except Exception as e2: if cls._logger: cls._logger.error(f"无法启动WPS: {str(e2)}") # 清理资源 cls._safe_uninitialize() return False, f"无法启动PowerPoint或WPS: {str(e)}" cls._application.Visible = True # 打开演示文稿 try: cls._presentation = cls._application.Presentations.Open(ppt_path, WithWindow=True) except Exception as e: if cls._logger: cls._logger.error(f"打开PPT文件失败: {str(e)}") # 清理资源 cls._cleanup_resources() return False, f"打开PPT文件失败: {str(e)}" # 全屏放映(新增循环设置) try: slide_show_settings = cls._presentation.SlideShowSettings # 设置循环播放:PowerPoint和WPS的属性名不同,需分别处理 if is_powerpoint: # PowerPoint中,LoopUntilStopped=True 表示循环播放直到手动停止 slide_show_settings.LoopUntilStopped = True else: # WPS中,Loop=True 表示循环播放 slide_show_settings.Loop = True # 启动放映 slide_show_settings.Run() except Exception as e: if cls._logger: cls._logger.error(f"启动幻灯片放映失败: {str(e)}") # 清理资源 cls._cleanup_resources() return False, f"启动幻灯片放映失败: {str(e)}" # 最大化并置顶窗口 time.sleep(1) # 等待窗口创建 cls.maximize_window() cls._is_active = True cls._is_ready = True if cls._logger: cls._logger.info(f"PPT已全屏循环播放: {ppt_path}") return True, "PPT已全屏循环播放" except Exception as e: # 异常时清理资源 cls._cleanup_resources() if cls._logger: cls._logger.error(f"打开PPT失败: {str(e)}") return False, f"打开PPT失败: {str(e)}" @classmethod def _cleanup_resources(cls): """清理PPT相关资源""" if cls._presentation: try: cls._presentation.Close() cls._presentation = None except: pass if cls._application: try: cls._application.Quit() cls._application = None except: pass # 反初始化COM cls._safe_uninitialize() cls._is_active = False cls._is_ready = False @classmethod def _safe_uninitialize(cls): """安全地反初始化COM""" if cls._com_initialized: try: CoUninitialize() cls._com_initialized = False if cls._logger: cls._logger.debug("已反初始化COM") except Exception as e: if cls._logger: cls._logger.warning(f"反初始化COM失败: {str(e)}") else: if cls._logger: cls._logger.debug("COM未初始化,无需反初始化") @classmethod def maximize_window(cls): if not cls._presentation: return False try: def enum_windows_callback(hwnd, _): window_title = win32gui.GetWindowText(hwnd) if "PowerPoint Slide Show" in window_title or "WPS 演示" in window_title: # 先最大化窗口 win32gui.ShowWindow(hwnd, win32con.SW_MAXIMIZE) # 再设置窗口置顶(HWND_TOPMOST表示置顶,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE表示不改变位置和大小) win32gui.SetWindowPos( hwnd, win32con.HWND_TOPMOST, # 置顶标记 0, 0, 0, 0, win32con.SWP_NOMOVE | win32con.SWP_NOSIZE # 不改变位置和大小 ) if cls._logger: cls._logger.info(f"最大化并置顶窗口: {window_title}") win32gui.EnumWindows(enum_windows_callback, None) return True except Exception as e: if cls._logger: cls._logger.warning(f"最大化并置顶窗口失败: {str(e)}") return False @classmethod def navigate(cls, direction): """翻页操作:通过模拟键盘上下键实现(核心修改)""" if not cls._is_active or not cls._application or not cls._presentation: return False, "没有活跃的PPT或对象已失效" if not cls._is_ready: return False, "PPT正在加载中,请稍后" try: with cls._lock: # 检查放映窗口是否存在(确保PPT处于放映状态) if not hasattr(cls._presentation, 'SlideShowWindow') or cls._presentation.SlideShowWindow is None: return False, "幻灯片放映已终止,请重新打开" # 模拟键盘按键(上箭头=上一页,下箭头=下一页) if direction == 'next': pyautogui.press('down') # 模拟下箭头键 if cls._logger: cls._logger.info("模拟下箭头键,切换到下一页") return True, "已模拟下箭头键,切换到下一页" elif direction == 'previous': pyautogui.press('up') # 模拟上箭头键 if cls._logger: cls._logger.info("模拟上箭头键,切换到上一页") return True, "已模拟上箭头键,切换到上一页" else: return False, "无效的翻页方向" except Exception as e: if cls._logger: cls._logger.error(f"翻页失败: {str(e)}") return False, f"翻页失败: {str(e)}" @classmethod def close(cls): """关闭当前打开的PPT""" with cls._lock: # 使用线程锁确保线程安全 cls._cleanup_resources() if cls._logger: cls._logger.info("PPT已关闭") @classmethod def is_active(cls): """检查是否有活跃的PPT""" return cls._is_active @classmethod def is_ready(cls): """检查PPT是否准备好(可翻页)""" return cls._is_ready class WebController: """控制网页的全屏显示""" _driver = None # WebDriver实例 _lock = threading.Lock() # 添加线程锁 _logger = None # 日志记录器 @classmethod def set_logger(cls, logger): """设置日志记录器""" cls._logger = logger @classmethod def open_fullscreen(cls, url, browser_type='chrome'): """ 在浏览器中全屏打开网页 :param url: 要打开的URL :param browser_type: 浏览器类型,支持 'chrome', 'edge', 'firefox' :return: (成功与否, 消息) """ with cls._lock: # 使用线程锁确保线程安全 # 关闭已存在的浏览器实例 if cls._driver: try: cls._driver.quit() except: pass cls._driver = None try: # 根据浏览器类型创建driver if browser_type.lower() in ['chrome', 'googlechrome']: chrome_options = Options() chrome_options.add_argument("--kiosk") # 全屏模式 chrome_options.add_argument("--disable-infobars") chrome_options.add_experimental_option("useAutomationExtension", False) chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) # 设置WebDriver服务 service = Service(executable_path='chromedriver.exe') cls._driver = webdriver.Chrome(service=service, options=chrome_options) elif browser_type.lower() in ['edge', 'microsoftedge']: edge_options = Options() edge_options.add_argument("--kiosk") # 全屏模式 edge_options.add_argument("--disable-infobars") # 设置WebDriver服务 service = Service(executable_path='msedgedriver.exe') cls._driver = webdriver.Edge(service=service, options=edge_options) elif browser_type.lower() in ['firefox', 'mozilla']: firefox_options = webdriver.FirefoxOptions() firefox_options.add_argument("--kiosk") # 全屏模式 # 设置WebDriver服务 service = Service(executable_path='geckodriver.exe') cls._driver = webdriver.Firefox(service=service, options=firefox_options) else: if cls._logger: cls._logger.error(f"不支持的浏览器类型: {browser_type}") return False, f"不支持的浏览器类型: {browser_type}" # 打开URL cls._driver.get(url) # 确保全屏 try: # 尝试按F11实现全屏(某些浏览器需要) ActionChains(cls._driver).key_down(Keys.F11).perform() time.sleep(0.5) # 等待全屏生效 except: pass if cls._logger: cls._logger.info(f"已在{browser_type}中全屏打开: {url}") return True, f"已在{browser_type}中全屏打开" except Exception as e: if cls._logger: cls._logger.error(f"打开网页失败: {str(e)}") return False, f"打开网页失败: {str(e)}" @classmethod def close(cls): """关闭浏览器""" with cls._lock: # 使用线程锁确保线程安全 if cls._driver: try: cls._driver.quit() cls._driver = None if cls._logger: cls._logger.info("浏览器已关闭") return True except Exception as e: if cls._logger: cls._logger.error(f"关闭浏览器失败: {str(e)}") return False return True def kill_process_by_name(process_names, logger=None): """根据进程名杀死进程""" for proc in psutil.process_iter(['name']): try: if proc.info['name'] in process_names: proc.kill() if logger: logger.info(f"已结束进程: {proc.info['name']}") except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess) as e: if logger: logger.warning(f"无法结束进程: {e}") except Exception as e: if logger: logger.error(f"结束进程时出错: {e}") def cleanup_processes(logger=None): """清理可能残留的进程""" # 清理PPT相关进程 kill_process_by_name([ "POWERPNT.EXE", # PowerPoint "wpp.exe", # WPS演示 "et.exe", # WPS表格 "wps.exe", # WPS文字 "chrome.exe", # Chrome "msedge.exe", # Edge "firefox.exe" # Firefox ], logger=logger) 如果 不使用pycom 有没有办法控制ppt
最新发布
08-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值