如何使控制宽高比的中心面板

时间:2015-02-03 18:27:41

标签: python wxpython wxwidgets aspect-ratio

在wxPython中,我无法将我创建的子面板居中,以获得固定的宽高比。

要控制宽高比,子面板需要捕获Size事件,然后执行显式SetSize。所以,我已经做到了,效果很好。不幸的是,当我将这个子面板嵌入另一个面板(使用sizer)时,wx.ALIGN_CENTER_HORIZONTAL标志不起作用。

显然,sizer告诉我的子面板它的整个宽度都适合。当我的窗口不使用整个宽度时,sizer不会调整。这是我的代码的简化版本,显示了问题:

import wx

ROWS = 6
COLS = 25

class TestPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)

        label = wx.StaticText(self, -1, 'Label')
        grid  = TestGrid(self)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(label, 0, flag=wx.ALIGN_CENTER_HORIZONTAL)
        sizer.Add(grid,  1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.EXPAND)
        self.SetSizer(sizer)

class TestGrid(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent, -1)
        self.SetBackgroundColour(wx.BLUE)
        self.Bind(wx.EVT_SIZE,  self.OnSize)

    def OnSize(self, event):
        w, h = self.GetSizeTuple()
        delta = min(w // COLS, h // ROWS)
        self.SetSize((COLS*delta, ROWS*delta))
        self.Refresh()

if __name__ == '__main__':
    app = wx.App()
    frame = wx.Frame(None, -1, "Test", size=(600, 200))
    panel = TestPanel(frame)
    frame.Show(True)
    app.MainLoop()

这是一个截屏: Demonstration of problem

2 个答案:

答案 0 :(得分:0)

您无法或者至少不应该从自己的wxEVT_SIZE处理程序调整窗口大小。我不确定你想要实现什么,但如果目标是将所有内容封装在TestGrid类中,那么你应该让它具有它所具有的任何大小并在其中创建一个嵌套窗口会在OnSize中调整适当的大小。

答案 1 :(得分:0)

正如VZ在他的回答中所解释的那样,你的wxEVT_SIZE处理程序不是一个好主意。去掉它。使用sizer时,您必须在sizer基础结构中工作才能实现您的目标。

您希望TestGrid在其父级内填充尽可能多的空间,同时保持一定的宽高比;这正是wx.SHAPED的用途(与大于0的proportion相结合,你已经拥有)。因此,您应该将grid添加到sizer中,如下所示:

sizer.Add(grid,  1, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.SHAPED)

您需要做的唯一事情就是告诉sizer您所需的宽高比是多少。最简单的方法是为TestGrid设置初始大小(在添加到sizer之前);例如,设置其wxPanel基数的大小:

wx.Panel.__init__(self, parent, -1, size=(COLS*7, ROWS*7))

这就是它的全部内容。

(我只是猜测Python语法,所以忽略任何明显的错误:-))