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

wxPython:自动调整Frame尺寸以消除空白区域

wxPython窗口尺寸自适应问题解决

问题描述

开发的wxPython应用中,Frame包含两个控件:

  • control1:调整尺寸时保持宽高比
  • control2:高度固定,填满Frame整个宽度

使用带wx.SHAPED属性的BoxSizer布局control1后,初始显示正常:
初始Frame布局

但横向拖动Frame边框调整宽度时,因Frame高度固定,control1维持宽高比,右侧出现红色空白:
横向调整后的Frame

期望横向调整时Frame自动纵向调整,消除空白,达到如下效果:
自动调整高度后的横向调整Frame

纵向拖动边框调整高度时也存在同样的空白问题。

原代码如下:

import wx

app = wx.App()
frame = wx.Frame(None)
frame.SetBackgroundColour(wx.Colour(0xFF, 0, 0))

sizer = wx.BoxSizer(wx.VERTICAL)

control1 = wx.Panel(frame, size=(640, 360))
control1.SetBackgroundColour(wx.Colour(0x40, 0x40, 0x40))
sizer.Add(control1, 0, wx.EXPAND | wx.SHAPED)

control2 = wx.Panel(frame, size=(32, 32))
control2.SetBackgroundColour(wx.Colour(0, 0, 0))
sizer.Add(control2, 0, wx.EXPAND)

frame.SetSizerAndFit(sizer)
frame.Show()
app.MainLoop()

解决方案

重写Frame的OnSize事件处理方法,根据control1的宽高比和当前窗口尺寸,计算合适的窗口尺寸并自动调整,同时避免循环触发调整事件。

修改后的代码:

import wx

class AdaptiveFrame(wx.Frame):
    def __init__(self, parent):
        super().__init__(parent)
        self.SetBackgroundColour(wx.Colour(0xFF, 0, 0))
        
        # 记录control1的初始宽高比
        self.control1_aspect_ratio = 640 / 360
        
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        
        self.control1 = wx.Panel(self, size=(640, 360))
        self.control1.SetBackgroundColour(wx.Colour(0x40, 0x40, 0x40))
        self.sizer.Add(self.control1, 0, wx.EXPAND | wx.SHAPED)
        
        self.control2 = wx.Panel(self, size=(32, 32))
        self.control2.SetBackgroundColour(wx.Colour(0, 0, 0))
        self.sizer.Add(self.control2, 0, wx.EXPAND)
        
        self.SetSizerAndFit(self.sizer)
        
        # 绑定尺寸变化事件
        self.Bind(wx.EVT_SIZE, self.OnSize)
        # 防止重复触发调整的标记
        self.is_resizing = False

    def OnSize(self, event):
        if self.is_resizing:
            event.Skip()
            return
        
        self.is_resizing = True
        
        current_size = self.GetSize()
        control2_height = self.control2.GetSize().height
        
        # 根据当前宽度计算control1应有的高度,加上control2高度得到窗口总高度
        expected_control1_height = current_size.width / self.control1_aspect_ratio
        expected_frame_height = expected_control1_height + control2_height
        
        # 差异超过1像素时调整窗口高度,避免频繁触发
        if abs(current_size.height - expected_frame_height) > 1:
            self.SetSize(wx.Size(current_size.width, expected_frame_height))
        
        self.is_resizing = False
        event.Skip()

app = wx.App()
frame = AdaptiveFrame(None)
frame.Show()
app.MainLoop()

代码说明

  • 自定义AdaptiveFrame类继承wx.Frame,重写OnSize方法处理尺寸变化
  • 初始记录control1的宽高比(16:9),作为后续尺寸计算的依据
  • 在尺寸变化事件中,根据当前窗口宽度计算control1的适配高度,叠加control2的固定高度得到窗口预期总高度
  • 添加is_resizing标记,避免窗口尺寸调整再次触发EVT_SIZE事件导致循环
  • 纵向调整时,可复用逻辑,根据当前高度计算适配宽度,实现双向自适应

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:37:23