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
相关产品推荐
相关产品推荐

