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

PySimpleGUI窗口宽高比固定实现求助:Win32Gui方案无法正常工作

PySimpleGUI窗口固定宽高比实现方案

要让PySimpleGUI的可调整大小窗口保持固定宽高比,拖动宽度时自动调整高度匹配设定比例,这里提供一个可行的实现方案,解决之前用win32gui.MoveWindow失效的问题:

核心思路

  • 监听PySimpleGUI的WIN_RESIZED事件,捕捉窗口大小变化
  • 区分窗口整体尺寸和客户区(内容区域)尺寸——窗口边框、标题栏会占用额外空间,直接用整体尺寸计算比例会出错
  • 基于设定的客户区宽高比,计算调整后的整体窗口高度,再用Win32API调整窗口大小

完整代码

import PySimpleGUI as sg
import win32gui
import win32api
import win32con

def get_client_rect(hwnd):
    # 获取窗口内容区域(不含边框、标题栏)的尺寸
    client_rect = win32gui.GetClientRect(hwnd)
    return client_rect[2] - client_rect[0], client_rect[3] - client_rect[1]

def get_window_rect(hwnd):
    # 获取窗口整体的尺寸(包含边框、标题栏)
    window_rect = win32gui.GetWindowRect(hwnd)
    return window_rect[2] - window_rect[0], window_rect[3] - window_rect[1]

def adjust_window_aspect_ratio(hwnd, target_ratio):
    try:
        # 获取当前窗口整体宽度和客户区尺寸
        current_win_w, current_win_h = get_window_rect(hwnd)
        client_w, client_h = get_client_rect(hwnd)
        
        # 计算窗口边框+标题栏的额外宽度和高度
        extra_w = current_win_w - client_w
        extra_h = current_win_h - client_h
        
        # 基于当前窗口整体宽度,计算符合比例的整体高度
        target_client_w = current_win_w - extra_w
        target_client_h = int(target_client_w / target_ratio)
        target_win_h = target_client_h + extra_h
        
        # 如果高度变化超过1像素,才调整窗口(避免频繁触发)
        if abs(target_win_h - current_win_h) > 1:
            x, y, _, _ = win32gui.GetWindowRect(hwnd)
            win32gui.MoveWindow(hwnd, x, y, current_win_w, target_win_h, True)
    except Exception as e:
        print(f"调整窗口尺寸出错: {e}")

# 设定目标宽高比(比如16:9,可自行修改为4/3、1/1等)
TARGET_ASPECT_RATIO = 16 / 9

# 创建允许调整大小的PySimpleGUI窗口
layout = [
    [sg.Text("拖动窗口宽度,高度会自动匹配设定比例")],
    [sg.Button("退出")]
]

window = sg.Window("固定宽高比窗口", layout, resizable=True)

while True:
    event, values = window.read(timeout=100)
    if event == sg.WIN_CLOSED or event == "退出":
        break
    # 窗口大小变化时触发比例调整
    if event == sg.WIN_RESIZED:
        hwnd = window.TKroot.winfo_id()
        adjust_window_aspect_ratio(hwnd, TARGET_ASPECT_RATIO)

window.close()

为什么之前的代码失效?

之前的代码手动硬编码标题栏厚度和额外宽度(比如加22),但不同系统、主题下的窗口边框、标题栏尺寸差异很大,固定值计算会导致比例偏差,甚至MoveWindow调用后尺寸不符合预期。通过GetClientRect和GetWindowRect的差值计算额外空间,能适配不同系统环境。

内容的提问来源于stack exchange,提问作者toyxyz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 02:20:19