如何在不调整框架大小的情况下将元素添加到 wx.Python 中的 sizer?

How can I add elements to a sizer in wx.Python without having to resize the frame?

我正在为大学开发一个项目,但我找不到一种方法可以将元素添加到 GridSizer 并在不调整框架大小的情况下将它们显示在它们的位置。我想为 GridSizer 预定义 space,即使它是空的,这样我可以在不调整大小的情况下看到变化,但我找不到如何去做。此图像显示发生了什么

调整框架大小之前

调整框架大小后

我知道面板没有,因为在开始时 GridSizer 是空的 这是我的代码:

class MyFrame(wx.Frame):

def generarListadoNiveles(self):
    cantidad_niveles = int(self.niveles[0])
    
    if (self.modo == 'inicio'):
        fich_niveles = open('niveles.txt','r')
        niveles = fich_niveles.readlines()
        cantidad_niveles = int(niveles[0])

        #Existe un fichero 'records.txt'
        if (os.path.isfile('records.txt') == True):
            fich_records = open('records.txt','r')
            records = fich_records.readlines()

        #No existe un fichero 'records.txt'
        else:
            fich_records = open('records.txt', 'w')
            fich_records.write('1' + '\n')
            for i in range (cantidad_niveles):
                fich_records.write('_' + '\n')
            fich_records.close()
            fich_records = open('records.txt', 'r')
            records = fich_records.readlines()
            
    #Generar listado de niveles a elegir
    niveles_validos = []
    niveles = (open('records.txt','r')).readlines()
    for i in range (1, int(niveles[0])+2):
        nivel = niveles[i]
        nivel = nivel.rstrip('\n')
        if (nivel == '_'):
            nivel = 'Nivel ' + str(i) + ': ' + 'sin record'
        else:
            nivel = 'Nivel ' + str(i) + ': ' + str(nivel) + 'ptos'
    
        niveles_validos.append(nivel)
        
    return niveles_validos

def __init__(self, *args, **kwds):
    # begin wxGlade: MyFrame.__init__
    kwds["style"] = kwds.get("style", 0) | wx.DEFAULT_FRAME_STYLE
    wx.Frame.__init__(self, *args, **kwds)
    self.SetSize((720,480))
    
    self.lista_opciones = wx.ListBox(self, wx.ID_ANY, choices=[])
    self.boton_comenzar = wx.Button(self, wx.ID_ANY, "Comenzar")
    self.boton_deshacer = wx.Button(self, wx.ID_ANY, "Deshacer")

    self.__set_properties()
    self.__do_layout()
    self.inicio()
    # end wxGlade

def inicio(self):
    #Establecer modo inicio
    self.modo = 'inicio'
    
    #Guardar coches de cada nivel
    self.niveles = (open('niveles.txt','r')).readlines()
    self.coches_niveles = []
    for i in range (10):
        self.coches_niveles.append([])
    nivel = -1
    for i in range (1,len(self.niveles)):
        aux = str(self.niveles[i])
        if '0' <= (aux[0]) <= '9':
            nivel += 1
        else:
            self.coches_niveles[nivel].append(aux)
    
    
    #Opciones de lista de niveles
    listado = self.generarListadoNiveles()
    for i in range (len(listado)):
        elemento = listado[i]
        self.lista_opciones.Append(listado[i])
    
    self.lista_opciones.Bind(wx.EVT_LISTBOX, self.manejarNivel)
        
    #Desactivar botón de deshacer
    self.boton_deshacer.Disable()
    
    #Mensaje de seleccionar nivel
    self.texto_mensajes.SetLabel("Elija un nivel y pulse comenzar para empezar a jugar")
    
    #Añadir eventos
    
    
def __set_properties(self):
    # begin wxGlade: MyFrame.__set_properties
    self.SetTitle("frame")
    # end wxGlade


def __do_layout(self):
    # begin wxGlade: MyFrame.__do_layout
    sizer_1 = wx.BoxSizer(wx.HORIZONTAL) 
    sizer_3 = wx.BoxSizer(wx.HORIZONTAL) 
    self.grid_sizer_1 = wx.GridSizer(8, 8, 0, 0 | wx.EXPAND)
    
    #Sizer de parte izquierda
    sizer_2 = wx.BoxSizer(wx.VERTICAL)
    sizer_2.Add(self.lista_opciones, 0, wx.EXPAND, 0)
    sizer_2.Add(self.boton_comenzar, 0, wx.ALIGN_CENTER, 0)
    sizer_2.Add(self.boton_deshacer, 0, wx.ALIGN_CENTER, 0)
    
        
    texto_contador = wx.StaticText(self, wx.ID_ANY, "Tiempo restante (segundos): ")
    self.texto_mensajes = wx.StaticText(self, wx.ID_ANY, "")
    sizer_2.Add(texto_contador, 1, wx.ALIGN_CENTER, 0)
    sizer_2.Add(self.texto_mensajes, 0, 0, 0)
    

    sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
    sizer_1.Add(sizer_3, 1, wx.EXPAND, 0)
    
    
    sizer_3.Add(self.grid_sizer_1, 1, wx.EXPAND, 0)
    self.SetSizer(sizer_1)
    self.Layout()
        
        
def crearTablero(self, nivel):
    self.tablero = Tablero(self.nivel_actual)
    lista_coches = self.coches_niveles[self.nivel_actual-1]
    #Añadir los coches al tablero
    abc = ord('A')
    for i in range (len(lista_coches)):
        aux = lista_coches[i]
        coche = Coche(chr(abc),aux[0],aux[1],aux[2],aux[3]) #Orientación,columna,fila,longitud
        self.tablero.insertar_coche(coche)
        abc += 1

    self.visualizarTablero()
    
def visualizarTablero(self):
    matriz = self.tablero.get_estado_matriz()
    
    for i in range (8):
        if i == 0: 
            for j in range (8):
                panel = wx.Panel(self, wx.ID_ANY)
                panel.SetBackgroundColour(wx.Colour(155, 64, 64))
                self.grid_sizer_1.Add(panel, 1, wx.EXPAND, 0)
            
#EVENTOS

def manejarNivel(self, event):
    if (self.modo == 'inicio'):
        self.nivel_actual = self.lista_opciones.GetSelection() + 1
        print(self.nivel_actual)
        self.crearTablero(self.nivel_actual)

将面板添加到 gridsizer 后,您需要在框架上调用 Layout() 才能在适当的位置看到新添加的 windows。

self.Layout()

如果在任何情况下调用 Layout() 的次数太多,您会看到 child windows 一个接一个地添加,您可以针对它执行以下操作:冻结您的框架,然后解冻后。

self.Freeze()

#self.Layout() calls

self.Thaw()