Set up sizers correctly

2

I'll briefly comment on the problem:

I would like to design a GUI that consists of a window of a given size (say 500x600 pixels) and inside it in descending order we would have two rows one under the other with a label and a text box (where to enter data, but that's covered), a text box to dump information and under this last element three buttons.

I have not handled much with Sizers but I think I understand 'more or less' how they work ... However, I can not resize the window initially and the buttons are disproportionate. I have attached my code to see if you can help me:

import wx
class GUI(wx.Frame):
    def __init__(self,*args,**kwargs):
        #Iniciamos el frame
        wx.Frame.__init__(self,*args,**kwargs)

        #creamos los sizers
        #-----------------------------------------------
        #para la seccion principal
        self.sizerB=wx.BoxSizer(wx.VERTICAL)
        #para la seccion de los botones
        self.sizerButtons=wx.BoxSizer(wx.HORIZONTAL)
        #para la seccion de Mensaje y Comando
        self.sizerGrid=wx.FlexGridSizer(rows=2,cols=2,vgap=5,hgap=5)
        #------------------------------------------------

        #creamos las etiquetas
        #------------------------------------------------
        self.Mensaje=wx.StaticText(self,wx.ID_ANY,"Mensaje")
        self.Comando=wx.StaticText(self,wx.ID_ANY,"Comando")
        #-------------------------------------------------

        #Cajas de texto
        #-------------------------------------------------
        self.CajaM=wx.TextCtrl(self,wx.ID_ANY)
        self.CajaC=wx.TextCtrl(self,wx.ID_ANY)
        #-------------------------------------------------

        #creamos los botones(x3)
        #-------------------------------------------------
        self.SendM=wx.Button(self,wx.ID_ANY,"Enviar Mensaje")
        self.SendC=wx.Button(self, wx.ID_ANY, "Enviar Comando")
        self.Exit=wx.Button(self,wx.ID_ANY,"Salir")
        #--------------------------------------------------

        #Agregamos sizers(configurarlos despues)
        #--------------------------------------------------
        #agregaremos el flexigridsizer para las dos primeras cajas y etiquetas
        for obj in [self.Mensaje,self.CajaM,self.Comando,self.CajaC]:
            self.sizerGrid.Add(obj,1,wx.EXPAND | wx.ALL,2)
        self.sizerGrid.AddGrowableCol(1)

        #Ahora le toca a los botones
        for obj in [self.SendM,self.SendC,self.Exit]:
            self.sizerButtons.Add(obj,1,wx.EXPAND|wx.ALL)
            self.SetInitialSize((600,500))

        #---------------------------------------------------

        #Configuramos los sizers
        #---------------------------------------------------
        self.sizerB.Add(self.sizerGrid,2,1,wx.EXPAND|wx.ALL,5)
        self.sizerB.Add(self.sizerButtons,2,1,wx.EXPAND|wx.ALL,5)
        self.SetSizer(self.sizerB)
        #----------------------------------------------------

        self.Centre(True)
        self.Show()

if __name__=="__main__":
    app=wx.App()
    fr=GUI(None,-1,"Aplicacion",size=(300,200))
    app.MainLoop()
    
asked by AlexGA93 01.03.2018 в 16:15
source

1 answer

0

The key to doing what you want is to use the proportion of your BoxSizer appropriately. This parameter indicates whether the sizer is stretchable in the main orientation and what part of the available space the item occupies.

If the ratio is 0 , then the minimum size will be used to contain the item ; if it is 1 , it will receive a part of the available size (after what remains of subtracting the space of the items of fixed size); if you use 2 , you will receive two parts, etc. For example, if you have a BoxSizer horizontal with three buttons, if you assign 1 to the first one, to the second 2 and to the third 3 what it does is divide the space into six parts, the first button will have one sixth of the available horizontal space of the sizer , the second will be double the width of the first and the third will triple.

In your case you add two sizers to your% main% co and in both cases specify the BoxSizer parameter in 2. This implies that they are each half the size of the > sizer principal.

Taking into account the above and nesting sizers properly we can get what you want, one possibility is the following:

import wx



class GUI(wx.Frame):
    def __init__(self,*args,**kwargs):
        # Iniciamos el frame
        super(GUI, self).__init__(*args, **kwargs)

        # Creamos un panel principal
        self.panel = wx.Panel(self)

        # Creamos los sizers
        #-----------------------------------------------
        self.main_vbox = wx.BoxSizer(wx.VERTICAL)
        self.form_fgrid = wx.FlexGridSizer(rows=2, cols=2, vgap=5, hgap=5)
        self.info_hbox = wx.BoxSizer(wx.HORIZONTAL)
        self.button_hbox = wx.BoxSizer(wx.HORIZONTAL)
        #-----------------------------------------------

        # Creamos las etiquetas
        #------------------------------------------------
        self.mensaje = wx.StaticText(self.panel, wx.ID_ANY, "Mensaje")
        self.comando = wx.StaticText(self.panel, wx.ID_ANY, "Comando")
        #-------------------------------------------------

        # Creamos las cajas de texto
        #-------------------------------------------------
        self.caja_mensaje = wx.TextCtrl(self.panel, wx.ID_ANY)
        self.caja_comando = wx.TextCtrl(self.panel, wx.ID_ANY)
        #-------------------------------------------------

        # Creamos la caja para mostrar la informacion
        #-------------------------------------------------
        self.informacion = wx.TextCtrl(self.panel, wx.ID_ANY, "", wx.Point(-1, -1), wx.Size(-1, -1), wx.TE_MULTILINE)
        #-------------------------------------------------

        # Creamos los botones(x3)
        #-------------------------------------------------
        self.send_mensaje = wx.Button(self.panel, wx.ID_ANY, "Enviar Mensaje", size=(0, 35))
        self.send_comando = wx.Button(self.panel, wx.ID_ANY, "Enviar Comando", size=(0, 35))
        self.send_exit = wx.Button(self.panel, wx.ID_ANY, "Salir", size=(0, 35))
        #--------------------------------------------------

        # Configuramos los sizers
        #-------------------------------------------------
        # Añadimos etiquetas y cajas de texto a su FlexGrid
        self.form_fgrid.AddMany([(self.mensaje, 1),
                                 (self.caja_mensaje, 1, wx.EXPAND),
                                 (self.comando, 1),
                                 (self.caja_comando, 1, wx.EXPAND)])
        self.form_fgrid.AddGrowableCol(1, 1)

        # Añadimos la caja de texto para mostrar la información a su HBox
        self.info_hbox.Add(self.informacion, 1, wx.EXPAND)

        # Añadimos los botones a su HBox
        self.button_hbox.AddMany([(self.send_mensaje, 2, wx.EXPAND | wx.RIGHT, 10),
                                  (self.send_comando, 2, wx.EXPAND | wx.RIGHT, 10),
                                  (self.send_exit, 1, wx.EXPAND)])

        # Añadimos todos los sizers al VBox principal
        self.main_vbox.Add(self.form_fgrid, 0, wx.EXPAND | wx.ALL, 10)
        self.main_vbox.Add(self.info_hbox, 1,  wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
        self.main_vbox.Add(wx.StaticLine(self.panel), 0, wx.EXPAND, 5)
        self.main_vbox.Add(self.button_hbox, 0, wx.EXPAND | wx.ALL, 10)
        #-------------------------------------------------

        self.panel.SetSizer(self.main_vbox)
        self.Centre(True)
        self.Show()


if __name__ == "__main__":
    app = wx.App()
    GUI(None, -1, "Aplicacion", size=(500, 600))
    app.MainLoop()

With this we obtain the following:

The window initially has dimensions of 500x600 but can be resized or maximized without problems. If we resize the window, both the buttons and the initial form adapt to the width of the window, but the height is fixed. The proportion central% instead occupies all the width and height always available.

    
answered by 03.03.2018 / 19:05
source