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

如何在PySimpleGUI中实现窗口resize时Graph元素及绘图同步缩放

解决PySimpleGUI Graph元素同步窗口缩放的问题

核心思路是用相对比例而非固定像素值定义绘图元素,同时通过尺寸判断避免resize循环事件。以下是可直接运行的实现方案:

关键步骤

  • 初始化时记录Graph的原始尺寸,并用相对比例保存绘图元素的参数(比如圆心位置、半径占Graph宽高的比例)
  • 处理窗口resize事件时,仅当Graph的实际尺寸发生变化时才更新
  • 重新计算所有绘图元素的绝对坐标和大小,刷新Graph内容

完整代码示例

import PySimpleGUI as sg

# 初始化参数
DEFAULT_WIDTH = 400
DEFAULT_HEIGHT = 300
# 用相对比例定义绘图元素(圆心在中心,半径占短边的20%)
circle_params = {"center_ratio": (0.5, 0.5), "radius_ratio": 0.2}

# 布局:让Graph占满窗口
layout = [
    [sg.Graph(
        canvas_size=(DEFAULT_WIDTH, DEFAULT_HEIGHT),
        graph_bottom_left=(0, 0),
        graph_top_right=(DEFAULT_WIDTH, DEFAULT_HEIGHT),
        key="-GRAPH-",
        expand_x=True,
        expand_y=True
    )]
]

window = sg.Window("同步缩放示例", layout, resizable=True, finalize=True)
graph = window["-GRAPH-"]

# 绘制/重绘圆圈的函数
def draw_circle(graph, width, height):
    center_x = width * circle_params["center_ratio"][0]
    center_y = height * circle_params["center_ratio"][1]
    # 取宽高中的较小值计算半径,保证圆圈不变形
    radius = min(width, height) * circle_params["radius_ratio"]
    # 清除旧元素(如果存在)
    if graph.get_figures():
        graph.delete_figure(graph.get_figures()[0])
    # 绘制新圆圈
    graph.draw_circle((center_x, center_y), radius, fill_color="red")

# 首次绘制
draw_circle(graph, DEFAULT_WIDTH, DEFAULT_HEIGHT)
last_size = (DEFAULT_WIDTH, DEFAULT_HEIGHT)

while True:
    event, values = window.read()
    if event == sg.WINDOW_CLOSED:
        break
    # 处理窗口resize事件
    if event == sg.EVENT_WINDOW_RESIZED:
        current_size = graph.get_size()
        # 仅当尺寸真的变化时执行更新,避免循环触发resize
        if current_size != last_size:
            last_size = current_size
            # 同步Graph的坐标范围与当前画布尺寸
            graph.change_coordinates((0, 0), current_size)
            # 重绘圆圈
            draw_circle(graph, *current_size)

window.close()

代码说明

  1. 相对比例定义:圆圈的圆心和半径都用占Graph宽高的比例表示,无论窗口如何调整,元素始终保持相对位置和比例
  2. 避免resize循环:通过last_size记录上一次的Graph尺寸,仅当当前尺寸与上次不同时才执行更新,防止change_coordinates或重绘触发重复resize事件
  3. 坐标范围同步:每次resize时调用change_coordinates,让Graph的坐标范围与画布尺寸匹配,保证绘图逻辑的一致性
  4. 清除旧元素:重绘前删除旧图形,避免画布残留多个元素

这样实现后,拖动窗口边缘调整大小时,Graph会自动占满窗口,圆圈同步缩放且保持比例,不会出现循环触发resize的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 00:09:24