2009-12-31 5 views
0

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

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

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

Извинившись моим ужасным ASCII искусства, рама по существу имеет горизонтальный Sizer на нем, с 2-мя вертикальные дробилками, один для левого и один на право , Каждый из них имеет в себе панель, каждая из которых имеет в себе второй сизер. В левом sizer имеется проставка шириной 64 пикселя, а затем гридизатор, который позже заполняется изображениями. Правильный второй sizer является пользователем значительным, но минимум 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) 

Это работает, но контакты сетку в верхнем левом углу всего кадра, а не в верхнем левом углу правой га lf кадра - что он должен быть включен. Есть аналогичный код, чтобы сделать сетку 1x256 на левом фрейме, но я не могу сказать, страдает ли эта проблема по очевидным причинам. У обоих есть рабочие полосы прокрутки, но при перерисовании возникают проблемы с перерисованием, что заставляет задуматься, рисует ли он изображение по всему приложению и просто игнорирует макет приложения.

Что-то я пропустил здесь? Это первый раз, когда я делал что-либо с гридизаторами, изображениями и графическими интерфейсами вообще в python, только недавно начав с языка после того, как захотел написать что-то немного более кросс-платформенное, чем VB6 - какие-нибудь мысли? =/

ответ

1

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

Также вы когда-нибудь называли self.SetSizer (self.h_sizer)? Ничего не видел.

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

create_controls 
    create_left_panel 
     create_grid 
    create_right_panel 

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

+0

Я называю self.SetSizer (self.h_sizer), да - \t \t self.SetSizer (я.h_sizer) \t \t #set размер окна до минимального размера, способного \t \t self.SetSize (self.h_sizer.GetMinSize()) \t \t #set Минимальный размер окна может иметь такие размеры, чтобы \t \t себе .SetMinSize (self.h_sizer.GetMinSize()) находится непосредственно под первой частью кода. Извините, должен был включить это. : P Что касается вашего предложения ImgPanel, я смущен - какую строку я должен менять и к чему? если это \t \t self.imgPanelGrid.append (ImgPanel.ImgPanel (самость, False)) Я попробовал несколько способов положить rightPanel и не могут получить его работу ... – user241308

+0

Игнорирование над комментарием спрашивать, что я должен меняется - я изменил его на \t \t \t self.imgPanelGrid.append (ImgPanel.ImgPanel (self.rightPanel, False)) И это работает, с прокруткой проблема исчезла! Спасибо! Что касается идеи отдельной функции - это то, что я могу хорошо изучить, спасибо за предложение. – user241308

+0

Фактически, единственная проблема заключается в том, что по какой-то причине горизонтальная полоса прокрутки не работает, пока вертикальная она делает ... Она перемещается в правильном количестве приращений, которые она должна делать для доступных данных (3 возможных положения) но сетка не движется. – user241308