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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:45:29