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, я даже не знал, что это может принять аргументы!