wxPython GridSizer не прикреплен к панели?

Я пытаюсь создать редактор уровней для игры, над которой я работаю. Он извлекает данные из плоского файла, а затем, основываясь на побайтном поиске, собирает сетку из заданных плиток. С этой частью приложения у меня не должно быть проблем. Проблема в том, что моя тестовая версия редактора, которая загружает сетку тестовых тайлов размером 16x16 от 00 до FF, загружается не в том месте.

Пример: фрейм приложения выглядит следующим образом:

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

Исключая мое ужасное искусство ASCII, рамка имеет горизонтальный размер, с двумя вертикальными размерами: один слева и один справа. У каждого из них есть панель, в которой есть второй классификатор. В левом классификаторе есть разделитель шириной 64 пикселя, затем гридзайзер, который позже заполняется изображениями. Правый второй классификатор имеет размер, определяемый пользователем, но содержит не менее 960 пикселей через разделитель, а затем гридзайзер, который определяется шириной и высотой уровня в коде.

По существу, для каждой стороны - внутри сортировщика есть гридзайзер, который имеет распорку для ширины секции, которая находится на панели, которая находится внутри калибратора для той половины калибратора, которая находится в основной раме. Я надеюсь, что это имеет смысл, так как это иногда смущает меня: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 из указанного каталога, но для целей тестирования я просто генерирую сетку 16x16 от 00 до FF, как упомянуто выше, - с помощью параметра меню Я называю этот метод:

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, только недавно начав с языка после того, как захотел написать что-то более кроссплатформенное, чем VB6 - есть мысли? знак равно

1 ответ

Решение

Это много кода и много классификаторов! Но я думаю, что, возможно, ваши ImgPanels должны иметь права как родительский элемент, а не себя.

Кроме того, вы когда-нибудь вызывали self.SetSizer(self.h_sizer)? Такого не видел нигде.

Я рекомендую создавать части макета в отдельных функциях. Тогда вам не нужно беспокоиться о том, что ваше локальное пространство имен будет загрязнено всеми этими причудливыми именами классификаторов. Таким образом, для каждой части иерархии Sizer у вас может быть функция.

create_controls
    create_left_panel
        create_grid
    create_right_panel

Кроме того, я обычно использую SetMinSize на дочерних элементах управления вместо того, чтобы добавлять фиктивные проставки в размеры для настройки ограничений размера. Тогда Фит сделает это за тебя. Говоря о Fit, я даже не знал, что это может принять аргументы!

Другие вопросы по тегам