SetSizer、SetSizerAndFit 和调整组件大小
所以我有一个 wx.Frame,我在其中添加了 GLCanvas 和一些按钮。以下是广告的部分:
self.sizer = wx.FlexGridSizer(2,2,20,20)
self.xSize = FRAME_WIDTH - MIN_BUT_SIZE
self.ySize = FRAME_HEIGHT - 40
self.canvas = myGLCanvas(self, size=(self.xSize, self.ySize))
self.panel = GLPanel(self, canvas=self.canvas)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.sizer.Add(self.panel, 0, wx.EXPAND)
self.headerSizer.DeleteWindows()
self.centerSizer.Remove(self.headerSizer)
self.Layout()
self.centerSizer.Add(self.sizer)
self.goBack = wx.Button(self, -1, str("Go Back!"))
self.sizer.Add(self.goBack, 0, wx.ALIGN_CENTER_HORIZONTAL, 2)
self.sizer.Add((20,20))
self.SetSizerAndFit(self.mainGrid)
self.Bind(wx.EVT_SIZING, self.OnSizing)
我必须在这里提到 self.centerSizer 已经添加到 self.mainGrid 中,以及我用于某些按钮的另一个大小调整器。现在,如果我使用 self.SetSizer(mainGrid) 而不是 SetSizerAndFit(),则在我手动调整框架大小之前,我在上述代码中添加的组件无法正确定位。使用 SetSizerAndFit 可以实现这一点。但现在我希望我的 gl 画布能够随着我的框架调整大小。所以我的方法是:
def OnSizing(self, event):
size = self.GetSize()
newCanvasXSize = size.GetWidth() - MIN_BUT_SIZE
newCanvasYSize = size.GetHeight() - 40
self.canvas.SetSize((newCanvasXSize, newCanvasYSize))
self.Layout()
但是这不起作用,我的画布保持与以前相同的大小。我在某处读到 SetSizerAndFit 还设置了 min_size,这就是调整大小不起作用的原因。但是,即使我将其保留在 SetSizer 中,并调整框架大小以使所有内容都正确定位,画布的大小调整也不起作用。删除和创建 GLCanvas 不是这里的选项,因为加载顶点需要相当长的时间。
编辑
好的,使用 SetSizer + Layout 即可完成定位。但是画布仍然无法正确调整大小。我在画布中绑定了一个 OnResize 到 EVT_SIZE :
def OnResize(self, e):
self.width, self.height = e.GetSize()
self.SetSize((self.width, self.height))
self.Layout()
我在这里打印了 self.width 和 self.height 来看看会发生什么。显示如下:
875 674 ---(这些是正确的值,但紧随其后) 640 520 ---(这些是创建画布时使用的默认值)
每次调整大小时都会重复这种模式。
EDIT2
好吧,上述行为是因为我的程序的一部分中仍然有 SetSizerAndFit 。如果我采用纯粹的 SetSizer + Layout 方法,就会发生这种情况。组件(我的 GLCanvas 和其他 3 个按钮)被添加到框架中相应的位置。然而: 1.框架没有调整到所需的大小,所以我的按钮位于框架之外的某个地方。 2.GLCanvas 已定位,但它不会显示任何内容,直到我自己执行调整大小事件。
3.也许不是直接连接,但可以减小最小尺寸吗?我这么问是因为如果我在画布上的调整大小处理程序中使用 SetMinSize() ,它只会在大小增加时调整大小。如果帧尺寸减小,画布仍保持旧的(较大的)最小尺寸。
EDIT3
好吧,经过一些调整,我设法让画布随框架调整大小。但现在我有另一个问题,我有一个带有一个画布的 Flex grid sizer 和三个如下所示的按钮:
http ://postimage.org/image/1cyhqqcck/
现在我已经成功地使我的画布随框架调整大小,但是调整大小时“点”、“三角形”和“返回”按钮保持在同一位置,并且画布刚刚覆盖他们起来。我调用 Layout() 没有任何效果。
So I have a wx.Frame to which I add a GLCanvas and some buttons. Here is the part that ads these:
self.sizer = wx.FlexGridSizer(2,2,20,20)
self.xSize = FRAME_WIDTH - MIN_BUT_SIZE
self.ySize = FRAME_HEIGHT - 40
self.canvas = myGLCanvas(self, size=(self.xSize, self.ySize))
self.panel = GLPanel(self, canvas=self.canvas)
self.sizer.Add(self.canvas, 1, wx.EXPAND)
self.sizer.Add(self.panel, 0, wx.EXPAND)
self.headerSizer.DeleteWindows()
self.centerSizer.Remove(self.headerSizer)
self.Layout()
self.centerSizer.Add(self.sizer)
self.goBack = wx.Button(self, -1, str("Go Back!"))
self.sizer.Add(self.goBack, 0, wx.ALIGN_CENTER_HORIZONTAL, 2)
self.sizer.Add((20,20))
self.SetSizerAndFit(self.mainGrid)
self.Bind(wx.EVT_SIZING, self.OnSizing)
I have to mention here that self.centerSizer is already added to self.mainGrid at this point along with another sizer that I user for some buttons. Now if I use self.SetSizer(mainGrid) instead of SetSizerAndFit(), the components I added in the above code are not positioned properly UNTIL I resize my frame manually. With SetSizerAndFit this works. But now I want my gl canvas to resize with my frame. So my approach is:
def OnSizing(self, event):
size = self.GetSize()
newCanvasXSize = size.GetWidth() - MIN_BUT_SIZE
newCanvasYSize = size.GetHeight() - 40
self.canvas.SetSize((newCanvasXSize, newCanvasYSize))
self.Layout()
However this doesnt work and my canvas stays the same size as before. I've read somewhere that SetSizerAndFit also sets the min_size and that is why resizing doesnt work with it. However, even if I leave it with SetSizer, and resize the frame so everything is positioned properly, the resizing of the canvas doesnt work. Deleting and creating the GLCanvas is not and option here since it takes quite some time to load my vertices.
EDIT
Ok using SetSizer + Layout gets the positioning done. However the Canvas still doesnt resize properly. I have a OnResize binded to EVT_SIZE in the canvas that does:
def OnResize(self, e):
self.width, self.height = e.GetSize()
self.SetSize((self.width, self.height))
self.Layout()
I printed the self.width and self.height here to see what happens. The display is like this:
875 674 --- (these are the values that are correct, but immediately after followed by)
640 520 --- (these are the default values the Canvas was created with)
This patters repeats itself for every resize.
EDIT2
Ok the above behaviour was because I still had a SetSizerAndFit in a part of my program. If I go for a pure SetSizer + Layout approach this is what happens. The components ( my GLCanvas and 3 other buttons) are added to the frame in their corresponding locations. However:
1.The frame is not resized to the needed size so my buttons are somewhere outside the frame.
2.The GLCanvas is positioned but it doesnt display anything UNTIL I do a resize event myself.
3.Maybe not dirrectly connected but it is possible to decrease min size? I'm asking because if I use SetMinSize() in the Resize handler on the canvas it resizes ONLY WHEN the size increases. If frame size decreases the canvas remains with the old(larger) min size.
EDIT3
Ok after some tweaking I managed to get my canvas to resize with the frame. But now I have another problem, I have a flex grid sizer with one canvas, and three buttons that looks like this:
http://postimage.org/image/1cyhqqcck/
Now I've managed to make my canvas resize with the frame, however the Points, Triangle and Go Back buttons stay on the same position when resizing and the canvas just covers them up. I've called Layout() with no appearent effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我记得,甚至 Robin Dunn(wxPython 的创建者)也不使用 SetSizerAndFit。如果稍微改变框架大小就可以正确定位内容,那么您只需要调用框架的 Layout() 方法即可。这可能也是您需要调用来解决 GLCanvas 部分的全部内容。回顾一下,跳过 SetSizerAndFit 并仅使用 SetSizer。
As I recall, even Robin Dunn (creator of wxPython) doesn't use SetSizerAndFit. If you can get the stuff positioned properly when you change the frame size slightly, then you only need to call the frame's Layout() method. That might be all you need to call to solve the GLCanvas part too. To recap, skip SetSizerAndFit and just use SetSizer.