wxPython GridSizer没有附加到面板?

时间:2009-12-31 02:59:01

标签: python image wxpython panel sizer

我正在尝试为我正在制作的游戏构建关卡编辑器。它从平面文件中提取数据,然后基于逐字节搜索,它将从预先设置的区块组装网格。应用程序的这一部分我应该没有问题。问题是我的编辑器的测试版本只是从00到FF加载了一个16x16网格的测试图块,但是加载到了错误的位置。

示例:应用程序框架如下所示:

|-T-------|
| |       |
| |       |
| |       |
| |       |
|---------|

激发我可怕的ASCII艺术,框架上基本上有一个水平尺寸,有2个垂直尺寸,一个用于左边,一个用于右边。每个都有一个面板,每个面板都有一个第二个sizer。左侧分级器中有一个64像素宽的垫片,然后是一个格栅化器,后来用图像填充。右边的第二个sizer是用户大小的,但是通过一个垫片至少有960个像素,然后是一个由代码中的级别宽度和高度决定的网格化器。

基本上,对于每一侧 - 有具有用于该部分的宽度,它们是面板适合该一半是在主框架上的分级机的分级机的内部上的隔离物的分级机内部的gridsizer。我希望这是有道理的,因为它有时让我困惑:P

以下是完成所有这些操作的代码:

    #Horizontal sizer
    self.h_sizer = wx.BoxSizer(wx.HORIZONTAL)
    #Vertical sizer
    self.v_sizer_left = wx.BoxSizer(wx.VERTICAL)
    self.v_sizer_right = wx.BoxSizer(wx.VERTICAL)

    #Create the 2 panels
    self.leftPanel = wx.ScrolledWindow(self, style = wx.VSCROLL | wx.ALWAYS_SHOW_SB)
    self.leftPanel.EnableScrolling(False, True)
    self.rightPanel = wx.ScrolledWindow(self, style = wx.VSCROLL | wx.ALWAYS_SHOW_SB)
    self.rightPanel.EnableScrolling(False, True)

    #Create a sizer for the contents of the left panel
    self.lps = wx.BoxSizer(wx.VERTICAL)
    self.lps.Add((64, 0)) #Add a spacer into the sizer to force it to be 64px wide
    self.leftPanelSizer = wx.GridSizer(256, 1, 2, 2) # horizontal rows, vertical rows, vgap, hgap
    self.lps.Add(self.leftPanelSizer)   #Add the tiles grid to the left panel sizer
    self.leftPanel.SetSizerAndFit(self.lps) #Set the leftPanel to use LeftPanelSizer (it's not lupus) as the sizer
    self.leftPanel.SetScrollbars(0,66,0, 0) #Add the scrollbar, increment in 64 pixel bits plus the 2 spacer pixels
    self.leftPanel.SetAutoLayout(True) 
    self.lps.Fit(self.leftPanel)


    #Create a sizer for the contents of the right panel
    self.rps = wx.BoxSizer(wx.VERTICAL)
    self.rps.Add((960, 0)) #Set it's width and height to be the window's, for now, with a spacer
    self.rightPanelSizer = wx.GridSizer(16, 16, 0, 0) # horizontal rows, vertical rows, vgap, hgap
    self.rps.Add(self.rightPanelSizer)  #Add the level grid to the right panel sizer
    self.rightPanel.SetSizerAndFit(self.rps)    #Set the rightPanel to use RightPanelSizer as the sizer
    self.rightPanel.SetScrollbars(64,64,0, 0)   #Add the scrollbar, increment in 64 pixel bits - vertical and horizontal
    self.rightPanel.SetAutoLayout(True)
    self.rps.Fit(self.rightPanel)


    #Debugging purposes. Colours :)
    self.leftPanel.SetBackgroundColour((0,255,0))
    self.rightPanel.SetBackgroundColour((0,128,128))

    #Add the left panel to the left vertical sizer, tell it to resize with the window (0 does not resize, 1 does). Do not expand the sizer on this side.
    self.v_sizer_left.Add(self.leftPanel, 1)
    #Add the right panel to the right vertical sizer, tell it to resize with the window (0 does not resize, 1 does) Expand the sizer to fit as much as possible on this side.
    self.v_sizer_right.Add(self.rightPanel, 1, wx.EXPAND)

    #Now add the 2 vertical sizers to the horizontal sizer.
    self.h_sizer.Add(self.v_sizer_left, 0, wx.EXPAND)   #First the left one...
    self.h_sizer.Add((0,704))                           #Add in a spacer between the two to get the vertical window size correct...
    self.h_sizer.Add(self.v_sizer_right, 1, wx.EXPAND)  #And finally the right hand frame.

获取所有数据后,应用程序将使用它从指定目录生成带有.png磁贴的级别布局,但出于测试目的,我只是生成从00到FF的16x16网格,如上所述 - 通过我称之为菜单选项的方法:

def populateLevelGrid(self, id):
    #This debug method fills the level grid scrollbar with 256 example image tiles
    levelTileset = self.levelTilesetLookup[id]
    #levelWidth = self.levelWidthLookup[id]
    #levelHeight = self.levelHeightLookup[id]
    #levelTileTotal = levelWidth * levelHeight

    levelTileTotal = 256    #debug line

    self.imgPanelGrid = []
    for i in range(levelTileTotal):
        self.imgPanelGrid.append(ImgPanel.ImgPanel(self, False))
        self.rightPanelSizer.Add(self.imgPanelGrid[i]) 
        self.imgPanelGrid[i].set_image("tiles/"+ levelTileset + "/" + str(i) + ".png")
    self.rightPanelSizer.Layout() 
    self.rightPanelSizer.FitInside(self.rightPanel)

这样可行,但将网格固定在整个框架的左上角,而不是框架右半部分的左上角 - 它应该打开。在左框架上有一个类似的代码可以做1x256网格,但由于显而易见的原因,我无法判断它是否会遇到同样的问题。两者都有工作滚动条但在滚动时有重绘问题,让我想知道它是否在整个应用程序上绘制图像而忽略了应用程序布局。

我在这里错过了什么吗?这是我第一次在python中使用网格化器,图像和GUI进行任何操作,最近才开始使用该语言之后想要写一些比VB6更具跨平台性的东西 - 任何想法? = /

1 个答案:

答案 0 :(得分:1)

这是很多代码和很多sizer!但我想也许你的ImgPanels应该有rightPanel作为他们的父亲,而不是自己。

另外,你有没有打电话给self.SetSizer(self.h_sizer)?没看到任何地方。

我建议在不同的功能中创建部分布局。然后,您不必担心您的本地命名空间被所有这些古怪的sizer名称污染。因此,对于sizer层次结构的每个部分,您都可以拥有一个函数。

create_controls
    create_left_panel
        create_grid
    create_right_panel

另外,我通常在子控件上使用SetMinSize,而不是在sizer中添加虚设间隔来设置大小约束。然后Fit会为你做。说到Fit,我甚至不知道它可以接受争论!