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 - есть мысли? знак равно


person user241308    schedule 31.12.2009    source источник


Ответы (1)


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

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

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

create_controls
    create_left_panel
        create_grid
    create_right_panel

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

person FogleBird    schedule 31.12.2009
comment
Я вызываю self.SetSizer (self.h_sizer), да - self.SetSizer (self.h_sizer) # Устанавливаем минимальный размер окна self.SetSize (self.h_sizer.GetMinSize ()) # Устанавливаем минимум размер окна может быть изменен до размера self.SetMinSize (self.h_sizer.GetMinSize ()) находится непосредственно под первым разделом кода. Извините, я должен был включить это. : P Что касается вашего предложения ImgPanel, я запутался - какую строку я должен изменить и на что? если это self.imgPanelGrid.append (ImgPanel.ImgPanel (self, False)) Я пробовал несколько способов вставить rightPanel и не могу заставить его работать ... - person user241308; 31.12.2009
comment
Не обращайте внимания на приведенный выше комментарий на вопрос, что мне следует изменить - я изменил его на self.imgPanelGrid.append (ImgPanel.ImgPanel (self.rightPanel, False)) И он РАБОТАЕТ, проблема с прокруткой исчезла! Спасибо! Что касается идеи отдельной функции - это то, что я вполне могу изучить, спасибо за предложение. - person user241308; 31.12.2009
comment
Фактически, единственная проблема заключается в том, что по какой-то причине кажется, что горизонтальная полоса прокрутки не работает, в то время как вертикальная работает ... Она перемещается с правильным количеством приращений, которое она должна делать для доступных данных (3 возможных положения), но сетка не движется. - person user241308; 31.12.2009