Posición y tamaño de los controles
IronPython - Diseño WinForms: Propiedades Location
y Size
Vamos a crear una aplicación winforms con ironpython para ver como posicionar y dar tamaño a los controles. Empecemos creando el esqueleto de la aplicación:
# -*- coding: utf-8 -*-
import sys, clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
from System.Windows.Forms import *
from System.Drawing import *
class MainForm(Form):
def __init__(self):
Form.__init__(self)
self.Text = 'Mi App'
self.Icon = Icon.ExtractAssociatedIcon(sys.executable)
self.ClientSize = Size(300, 100)
self.add_controls()
def add_controls(self):
pass
if __name__ == '__main__':
Application.EnableVisualStyles()
Application.Run(MainForm())
En el método MainForm.add_controls
añadiremos los controles.
Añadir un control al formulario
Vamos a añadir un Button
al formulario MainForm
:
def add_controls(self):
button = Button()
button.Text = 'Un botón'
self.Controls.Add(button)
El resultado es el siguiente:
El botón se encuentra en la esquina superior izquierda, ya que es la posición por defecto. Su tamaño también es asignado por defecto debido a que no lo hemos indicado explícitamente.
Para que el control sea visible hay que añadirlo a la colección Controls
del formulario: self.Controls.Add(button)
.
Si quieres eliminar un control en tiempo de ejecución puede utilizar el método Remove
de la colección Controls
del formulario: self.Controls.Remove(button)
.
Posición y tamaño del control
Continuando con el botón que hemos añadido anteriormente al formulario, ahora vamos a asignarle una posición y tamaño explícitamente:
def add_controls(self):
button = Button()
button.Text = 'Un botón'
button.Location = Point(50, 30)
button.Size = Size(100, 50)
self.Controls.Add(button)
Este código da el siguiente resultado:
La propiedad Location
define la posición del control en el eje de coordenadas de su contenedor (en este caso el formulario). Su valor debe ser una instancia de System.Drawing.Point
. El primer parámetro es la posición en el eje X y el segundo la posición en el eje Y.
La propiedad Size
define el tamaño del control. Su valor debe se una instancia de System.Drawing.Size
. El primer parámetro es el ancho y el segundo el alto.
Centrar un control
Vamos a intentar centrar nuestro botón. Fíjate que en el método __init__
hemos asignado un tamaño al formulario: self.ClientSize = Size(300, 100)
.
La propiedad ClientSize
del formulario define el tamaño del área en la que se dibujan los controles, es decir, es el tamaño del formulario sin incluir la caja de control (donde están los botones de minimizar, maximizar y cerrar el formulario).
Podemos utilizar self.ClientSize
para asignar a nuestros controles posiciones y tamaños relativos al tamaño del formulario. Por ejemplo:
def add_controls(self):
button = Button()
button.Text = 'Un botón'
button.Location = Point(self.ClientSize.Width/2, self.ClientSize.Height/2)
button.Size = Size(100, 50)
self.Controls.Add(button)
El resultado es el siguiente:
El ancho del formulario está almacenado en self.ClientSize.Width
, y su altura en self.ClientSize.Height
. Al asignar button.Location = Point(self.ClientSize.Width/2, self.ClientSize.Height/2)
el botón ¿está centrado? no lo está.
Lo que está centrado es la esquina superior izquierda del botón. Si queremos centrar el botón tenemos que tener en cuenta su propio tamaño:
def add_controls(self):
button = Button()
button.Text = 'Un botón'
button.Size = Size(100, 50)
x = int((self.ClientSize.Width - button.Size.Width) / 2)
y = int((self.ClientSize.Height - button.Size.Height) / 2)
button.Location = Point(x, y) # # x e y pueden ser <float> o <int> en ironpython, pero en pythonnet tienen que ser <int>
self.Controls.Add(button)
Ahora el botón si está centrado, ya que a su posición en X le restamos la mitad se su propio ancho, y a su posición en Y le restamos la mitad de su propia altura.
Fíjate en que para centrar el botón ha sido necesario definir su Size
antes que su Location
.
El único problema es que si el usuario cambia el tamaño del formulario el botón no se adapta:
De momento, la solución que vamos a dar va a ser impedir que se pueda cambiar el tamaño del formulario asignando self.FormBorderStyle = FormBorderStyle.FixedSingle
. Ya de paso, deshabilitaremos el botón de maximizar el formulario: self.MaximizeBox = False
.
Código final
El código completo de nuestra increible aplicación con un botón que no hace nada, pero perfectamente centrado, es el siguiente:
# -*- coding: utf-8 -*-
import sys, clr
clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
from System.Windows.Forms import *
from System.Drawing import *
class MainForm(Form):
def __init__(self):
Form.__init__(self)
self.Text = 'Mi App'
self.Icon = Icon.ExtractAssociatedIcon(sys.executable)
self.ClientSize = Size(300, 100)
self.MaximizeBox = False
self.FormBorderStyle = FormBorderStyle.FixedSingle
self.add_controls()
def add_controls(self):
button = Button()
button.Text = 'Un botón'
button.Size = Size(100, 50)
x = int((self.ClientSize.Width - button.Size.Width) / 2)
y = int((self.ClientSize.Height - button.Size.Height) / 2)
button.Location = Point(x, y) # x e y pueden ser <float> o <int> en ironpython, pero en pythonnet tienen que ser <int>
self.Controls.Add(button)
if __name__ == '__main__':
Application.EnableVisualStyles()
Application.Run(MainForm())
En la siguiente sección aprenderás a adaptar la posición y tamaño de los controles cuando cambia el tamaño del formulario.
Un saludo!