Kivy开发:如何让视频播放器窗口保持宽高比不变?
Kivy窗口保持宽高比例的解决方案
你的代码核心问题是:在on_resize回调中直接修改Window.size会触发新的on_resize事件,形成无限循环,导致窗口失控、无法操作。以下是两种符合需求的修正方案:
方案1:保持窗口整体初始宽高比例
如果需要窗口整体严格遵循初始的宽高比,可使用以下代码:
from kivy.core.window import Window from kivy.clock import Clock # 初始窗口尺寸 initial_w = 350 initial_h = round(initial_w / 16 * 9) + 60 Window.size = (initial_w, initial_h) # 计算初始宽高比 aspect_ratio = initial_w / initial_h # 标志位:防止递归触发resize事件 is_resizing = False def on_window_resize(window, width, height): global is_resizing if is_resizing: return is_resizing = True # 按当前宽度计算符合比例的高度(也可改为按高度计算宽度) new_h = round(width / aspect_ratio) # 延迟设置尺寸,避免触发新的resize循环 Clock.schedule_once(lambda dt: setattr(window, 'size', (width, new_h))) is_resizing = False Window.bind(on_resize=on_window_resize) Window.minimum_width = initial_w Window.minimum_height = initial_h
方案2:保持视频区域16:9比例(更适合视频播放器)
如果你的需求是视频显示区域保持16:9,窗口高度额外包含控件栏等固定高度,可使用此方案:
from kivy.core.window import Window from kivy.clock import Clock # 视频区域初始宽度 video_w = 350 # 视频区域16:9比例计算高度 video_h = round(video_w / 16 * 9) # 窗口额外高度(比如控件栏、状态栏) extra_h = 60 # 初始窗口尺寸 Window.size = (video_w, video_h + extra_h) # 视频区域宽高比 video_aspect = 16 / 9 is_resizing = False def on_window_resize(window, width, height): global is_resizing if is_resizing: return is_resizing = True # 根据当前窗口宽度,计算视频区域高度,再得到窗口总高度 new_video_h = round(width / video_aspect) new_window_h = new_video_h + extra_h # 若需要优先按高度调整宽度,可替换为以下代码: # new_video_h = height - extra_h # new_window_w = round(new_video_h * video_aspect) # Clock.schedule_once(lambda dt: setattr(window, 'size', (new_window_w, height))) Clock.schedule_once(lambda dt: setattr(window, 'size', (width, new_window_h))) is_resizing = False Window.bind(on_resize=on_window_resize) # 设置最小尺寸,防止额外高度被压缩 Window.minimum_width = video_w Window.minimum_height = video_h + extra_h
关键说明
- 避免递归循环:用
is_resizing标志位拦截回调的递归触发,因为修改窗口尺寸会再次触发on_resize事件。 - 延迟设置尺寸:通过
Clock.schedule_once让当前resize事件处理完成后再修改窗口大小,避免冲突。 - 明确比例逻辑:根据实际需求选择是保持窗口整体比例,还是内容区域比例,确保行为符合预期。
内容的提问来源于stack exchange,提问作者FelixTheCat
相关产品推荐
相关产品推荐

