SurfaceView


La clase SurfaceView se usa en juegos que necesitan un nivel bastante alto de potencia a la hora de repintar la pantalla.

En el siguiente ejemplo se muestra una imagen a través de SurfaceView


public class Game extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new GameView(this));
    }
}

public class GameView extends SurfaceView implements SurfaceHolder.Callback {

	private Bitmap bmp;
	private int width, height;
	private SurfaceHolder holder;

	public GameView(Context context) {
		super(context);
		getHolder().addCallback(this);
		bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		this.width = width;
		this.height = height;
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		Canvas c = holder.lockCanvas(null);
		onDraw(c);
		holder.unlockCanvasAndPost(c);
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {

	}

	@Override
	public void onDraw(Canvas canvas) {
		canvas.drawColor(Color.BLACK);
		canvas.drawBitmap(bmp, 10, 10, null);
	}

}

Se crea una clase que herede SurfaceView e implemente SurfaceHolder.callback para usar los métodos de esta última interfaz:


public class GameView extends SurfaceView implements SurfaceHolder.Callback {

No se puede manejar directamente el objeto Surface, se debe hacer a través de un SurfaceHolder (un contenedor) que se consigue llamando en el constructor de la clase a getHolder() e indicar que SurfaceHolder va a recibir las llamadas del SurfaceHolder.callback:


getHolder().addCallback(this);

Las siguiente tres funciones son propias del interfaz SurfaceHolder.Callback y se llaman en caso de que cambie el tamaño de la pantalla (por ejemplo al girar el teléfono), al crear la View y cuando se cierra.

La primera actualiza los atributos de ancho y alto de la pantalla


@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		this.width = width;
		this.height = height;
	}

La segunda crea la View:


@Override
	public void surfaceCreated(SurfaceHolder holder) {
		Canvas c = holder.lockCanvas(null);
		onDraw(c);
		holder.unlockCanvasAndPost(c);
	}

La tercera se usa para cerrar la pantalla:


@Override
	public void surfaceDestroyed(SurfaceHolder holder) {

	}

Sobrescribimos el método onDraw() para que dibuje la imagen en la pantalla:


@Override
	public void onDraw(Canvas canvas) {
		canvas.drawColor(Color.BLACK);
		canvas.drawBitmap(bmp, 10, 10, null);
	}

Imagen y Gráficos


En Android la pantalla está ocupada por una actividad que cuenta con una vista que contiene un lienzo. Usted tiene la oportunidad de aprovechar el lienzo sobrescribiendo el método View.onDraw() . El único parámetro para onDraw() es un lienzo en el que se pueda dibujar.
Esta es una forma de mostrar una imagen y dibujar gráficos en la pantalla.


public class Graphics extends Activity {
	/** LLama a la actividad una vez creada. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(new GraphicsView(this));

	}

public class GraphicsView extends View {

	private Paint paint;
	private Bitmap mBitmap;

	public GraphicsView(Context context) {
		super(context);

		mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);

	}

	@Override
	protected void onDraw(Canvas canvas) {

		paint = new Paint();
		paint.setColor(Color.GREEN);
		int x = (getWidth() / 2) - (mBitmap.getWidth() / 2);
		int y = (getHeight() / 2) - (mBitmap.getHeight() / 2);

		canvas.drawLine(40, getHeight() / 2, getWidth() - 40, getHeight() / 2,
				paint);

		paint.setColor(Color.LTGRAY);
		canvas.drawCircle(getWidth() / 2, getHeight() / 2, 40, paint);

		canvas.drawBitmap(mBitmap, x, y, null);

		paint.setStyle(Paint.Style.STROKE);
		paint.setColor(Color.BLUE);
		canvas.drawCircle(getWidth() / 2, getHeight() / 2, 100, paint);

		Rect rect1 = new Rect(40, 40, 100, getHeight() / 2 - 20);

		Rect rect2 = new Rect(getWidth() - 40 - 60, getHeight() / 2 + 20,
				getWidth() - 40, getHeight() - 40);

		paint.setColor(Color.MAGENTA);
		canvas.drawRect(rect1, paint);
		canvas.drawRect(rect2, paint);

	}

En la Activity Graphics, setContentView() toma como parámetro un objeto de la clase GraphicsView.


setContentView(new GraphicsView(this));

En la clase GraphicView sobrescribimos el método onDraw() con un Cambas como argumento.


@Override
	protected void onDraw(Canvas canvas) { }

Un Cambas es un lienzo que nos permite dibujar figuras o una imagen.
Para dibujar el Cambas toma generalmente como parámetros las coordenadas x, y más un objeto de la clase Paint. La clase Paint mantiene el estilo, color y otra información necesaria para dibujar gráficos como mapa de bits (bitmap), texto y figuras geométricas.

A modo de prueba en vez de usar para las coordenadas x, y valores enteros le paso valores fraccionarios del ancho y el alto para mantener la composición dentro de la pantalla tanto en la posición vertical como horizontal.

Se crea un objeto de la clase Paint para pasarle al Canvas.


private Paint paint;
paint = new Paint();
paint.setColor(Color.GREEN);

Para dibujar una línea se toma los valores de las coordenadas del punto inicial y del punto final de la recta más un objeto Paint.


canvas.drawLine(40, getHeight() / 2, getWidth() - 40, getHeight() / 2,
				paint);

Para dibujar un circulo los valores de las coordenadas x, y representan el centro, después el valor del radio y un objeto Paint, por defecto el circulo se dibuja relleno.


paint.setColor(Color.LTGRAY);
canvas.drawCircle(getWidth() / 2, getHeight() / 2, 40, paint);

Para mostrar una imagen primero se crea un campo del tipo Bitmap, se inicializa en el constructor de la clase y luego se dibuja con el Canvas.


private Bitmap mBitmap;
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
canvas.drawBitmap(mBitmap, x, y, null);

Con esto cambio el estilo del objeto Paint para que la figura no sea rellena.


paint.setStyle(Paint.Style.STROKE);

Con setColor() se establece el color del objeto Paint.


paint.setColor(Color.BLUE);

Para dibujar un rectángulo primero se crea un objeto Rect para usarlo en el Canvas.
Los valores x, y son la esquina superior derecha y el otros par de valores x’, y’ son la esquina inferior izquierda.


Rect rect1 = new Rect(40, 40, 100, getHeight() / 2 – 20);

Después se llama a canvas.drawRect() con los objetos Rect y Paint como argumento.


canvas.drawRect(rect1, paint);


Mostrar Imágen

Interesado en el desarrollo de juegos en Android empecé a estudiar esta plataforma.
Para programar en Android es necesario instalar Java, android-sdk y Eclipse, si no sabes como hacerlo podes recurrir a la documentación oficial, también aquí hay un video en español que lo explica muy bien como hacerlo.

Empecé a leer sobre como dibujar imágenes, según dice la documentación oficial Android provee la biblioteca de gráficos 2D para dibujar y animar forma é imágenes personalizadas. Los paquetes android.graphics.drawable y android.view.animation es donde se encuentran las clases más comunes que se utilizan para dibujar y animar en dos dimensión.
Para dibujar gráficos en aplicaciones android se puede utilizar objetos Drawable ó un par de subclases de Drawable para crear animaciones que puedan (moverse, girar ó rotar) un solo gráfico ó la animación de una serie de gráficos (como una película).
Los Drawables son todo aquello que se puede dibujar en una View (vista), es la clase de la cual heredan una variedad de tipos de gráficos, incluyendo BitmapDrawable, ShapeDrawable, PictureDrawable, LayerDrawable y otros. Hay tres maneras distintas de instanciar una clase Drawable.
- Utilizar una imagen almacenada en el directorio de recursos de nuestro proyecto.
- Utilizar un XML que define las propiedades del objeto para luego poder recuperarlo mediante getDrawable() y el ID que se le asignó en el XML.
- Utilizando los constructores propios de la clase.
____________________________________________________________
Creación de imágenes desde recursos

Una forma sencilla de agregar gráficos a su aplicación es por referencia a una imagen desde los recursos de su proyecto.
Los tipos de archivos soportados son PNG (preferidos), JPG (aceptables) y GIF (todos) .
Esta técnica, obviamente, sería preferible para los iconos, logotipos u otros gráficos como los utilizados en un juego.
Para utilizar un recurso de imagen, basta con añadir el archivo al directorio /res/drawable/ de su proyecto. Desde allí se puede hacer referencia desde el código o desde el Diseño XML.
De cualquier manera, se hace referencia mediante un identificador de recursos (id), que es el nombre del archivo sin la extensión del tipo de archivo (por ejemplo my_image.png se referencia como my_image).
Código de ejemplo

El siguiente fragmento de código muestra como crear una ImageView que utiliza la imagen de los recursos drawable y la agrega al diseño.

public class AgregarImagen extends Activity {
	/** inicia la actividad una vez creada. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Crear un LinealLayout en el que se agrega la ImageView
		LinearLayout mLinearLayout = new LinearLayout(this);

		// Instanciar una ImageView y definir sus propiedades
		ImageView i = new ImageView(this);
		i.setImageResource(R.drawable.images);
		i.setAdjustViewBounds(true); // establecer los limites de ImageView
		// con las dimensiones disponibles 

		i.setLayoutParams(new Gallery.LayoutParams(LayoutParams.WRAP_CONTENT,
				LayoutParams.WRAP_CONTENT));

		// Agregar la ImageView al diseño y definir el diseño como el contenido
		// de la vista
		mLinearLayout.addView(i);
		setContentView(mLinearLayout);

	}
}

Dentro del método onCreate que inicia la actividad se crea el campo mLinearLayout que hace referencia a un LinearLayout que es un contenedor de widgets que los muestra alineados horizontal o verticalmente.

Se crea el objeto i de la clase ImageView que hace referencia al padre View, ImageView permite cargar imagenes desde recursos externos calcular su tamaño y mostrarla en una vista, se busca la imagen guardada en R.drawable, se ajusta a las dimensiones disponibles, se establece los parámetros de diseño con un objeto Gallery para que la imagen ocupe solo el espacio necesario para mostrar su contenido .
Se agrega la imagen al diseño y se muestra el diseño en la vista.

De Python a Java

De Python a Java

La experiencia de haber estudiado los fundamentos de la programación con python fue muy buena y estoy de acuerdo de que es un muy buen primer lenguaje de programación.
El profesor que dicto el curso, sostenía que este era el mejor lenguaje de programación y que se debía usar para todo.
Sin entrar en fundamentalismos ni debates filosóficos, aceptando que python se aplica en muchas áreas, algunas con mucho éxito (como otros lenguajes de programación) sentí que tenia que investigar otras alternativas.
Empecé estudiando el lenguaje C, del cual se habla mucho de sus virtudes, algunos lo consideran el padre de todos los lenguajes y destacan su importancia para comprender los fundamentos de la programación.
Después de estudiar los conceptos básicos de C, para desarrollar la programación orientada a objetos debía seguir con C++. En ese momento descubrí Java por la demanda laboral que tenía causa por la cual en muchas facultades lo están enseñando.
Cuando lo comencé a investigar quede fascinado por muchas cosas de el que me gustaron, solo voy a comentar a nivel de experiencia personal las diferencia entre uno y otro que me llamaron la atención sin entrar en juicios de valor.
Python es un lenguaje interpretado el interprete convierte código fuente en lenguaje maquina, Java tiene una primera compilación que convierte al código fuente en bytecode (algo parecido a assembler) y después la máquina virtual de java JVM lo convierte en lenguaje máquina.
Python es multiparadigma, se puede programar en el aplicando muchos estilos diferentes de programación, Java solo permite programación orientada a objetos por considerar esta la mejor practica.
La documentación oficial de Java también me llamo la atención ordenada en una jerarquía de clases en formato de página web mucho más eficiente que la documentación de Python.
La sintaxis de Python es sintética y muy elegante es una de sus grandes virtudes, Java es más tipeado y extenso pero esto no llega a ser un impedimento por el uso de los IDE de programación.
A través de Java conocí a NetBeans y Eclipse dos entornos de programación gratuitos muy completos hechos en Java con los cuales mi inicio en este lenguaje fue un verdadero placer y cada día que los uso le descubro infinidad de recursos que facilitan y permiten el aprendizaje de pautas de diseño y buenos hábitos de programación en el desarrollo de aplicaciones Java.
Hace seis meses deje de programar en Python y me dedique de lleno a la programación en Java, esto me llevo a una comprensión más amplia y profunda de la programación orientada a objetos lo cual cambio mi visión sobre el diseño del software.
Valoro este cambió porque amplio el horizonte y la motivación por seguir en este apasionante camino de conocimiento.

Registro de usuarios

Django versión 1.0
SO Debian lenny
Necesito hacer un formulario de registro de usuario que contenga nombre de usuario correo electrónico y contraseña.
Si bien como dice el Django book en el capítulo 14 Django proporciona un formulario prefabricado que se puede usar con este fin con el modulo UserCreationForm como se describe en el ejemplo, este gestiona solo usuario y contraseña no posee campo de correo electrónico.
Por eso decidí crear un formulario que ingresara estos datos a bajo nivel como también se describe en ese capitulo del libro.

Para empezar agregue la siguiente entrada a urls.py


(r'^register/$', 'mysite.books.views.register'),

Luedo escribí la clase register_user formulario en forms.py

class register_user(forms.Form):
    usuario = forms.CharField(max_length=30)
    email = forms.EmailField()
    password1 = forms.CharField(max_length=10, widget= forms.PasswordInput)
    password2 = forms.CharField(max_length=10, widget= forms.PasswordInput)

Esta clase define los campos del formulario que son una entrada de usuario, e- mail, contraseña y repetir la contraseña.
En views.py primero importo desde forms.py register_user para usarlo en la función register.

from forms import register_user

Luego defino la función register de esta manera:


def register(request):
    if request.method == 'POST':
        form = register_user(request.POST)
        if form.is_valid():
            #cd = form.cleaned_data
            name_user = form.cleaned_data['usuario']
            email_user = form.cleaned_data['email']
            pass_user = form.cleaned_data['password1']
create_user = User.objects.create_user(username= name_user, email= email_user,
password=pass_user)

            create_user.is_staff = True
            create_user.save()
            return HttpResponseRedirect('/specials_books/')
    else:
        form = register_user()
    return render_to_response('registration/register.html', {'form': form})

Si hay un envío del formulario por medio del método POST accedo a los datos y los guardo en form, se validan y volvemos a acceder por medio de cleaned_data


name_user = form.cleaned_data['usuario']
            email_user = form.cleaned_data['email']
            pass_user = form.cleaned_data['password1']

Luego creamos un usuario con estos datos


create_user = User.objects.create_user(username= name_user, email= email_user,
password=pass_user)

Y luego los guardamos.


create_user.is_staff = True
create_user.save()

Esta vista asume que existe la carpeta registration y dentro el archivo register.html que sería algo así


<div class="form_subtitle">crear un nuevo usuario</div>
                 <form name="." method="post">          
                    <div class="form_row">
                    <div class="contact_input" />{{ form.usuario.errors }}</div>
                    <label class="contact"><strong>usuario:</strong></label>
                    <div class="contact_input" />{{ form.usuario }}</div>
                    </div>  

                    <div class="form_row">
                    <div class="contact_input" />{{ form.email.errors }}</div>
                    <label class="contact"><strong>Email:</strong></label>
                    <div class="contact_input" />{{ form.email }}</div>
                    </div>

                    <div class="form_row">
                    <div class="contact_input" />{{ form.password1.errors }}</div>
                    <label class="contact"><strong>contraseña:</strong></label>
                    <div class="contact_input" />{{ form.password1 }}</div>
                    </div>


                    <div class="form_row">
                    <div class="contact_input" />{{ form.password2.errors }}</div>
                    <label class="contact"><strong>de vuelta:</strong></label>

                    <div class="contact_input" />{{ form.password2 }}</div>
                    </div>

                    <div class="form_row">
                    <input type="submit" class="register" value="registrar" />
                    </div>   
                  </form>     
                </div>

Agregando más validación

Además del sistema de validación que proporciona el objeto form, decidí agregar dos mas, que la cantidad de dígitos de la contraseña no sea menor que cuatro y que sea necesario escribirla de vuelta.
Para ello se agrego dentro la clase register_user en el archivo forms.py las funciones
clean_password1 y clean_password2 quedando el código completo así.


class register_user(forms.Form):
    usuario = forms.CharField(max_length=30)
    email = forms.EmailField()
    password1 = forms.CharField(max_length=10, widget= forms.PasswordInput)
    password2 = forms.CharField(max_length=10, widget= forms.PasswordInput)

#Validar de la cantidad de letras del password
    def clean_password1(self):
        password1 = self.cleaned_data.get('password1', '')
        num_words = len(password1)
        if num_words < 4:
            raise forms.ValidationError('Ingrese mas de cuatro palabras')
        return password1
#Comparar las dos contraseñas
    def clean_password2(self):
        password1 = self.cleaned_data.get('password1', '')
        password2 = self.cleaned_data.get('password2', '')
        if password1 != password2:
            raise forms.ValidationError('Repita la contraseña correctamente')
        return password2

Todo esto puede verse funcionando en el proyecto webookstore donde fue usado.

ImageField

SO Debian lenny
Django version 1.0 final

Para usar el campo ImageField en mi modelo se necesita PIL (Python Imaging Library), la librería de tratamiento de imágenes para Python.

Primero verificar si tenemos instaladas las librerías de soporte para imágenes

sudo apt-get install libjpeg62-dev
sudo apt-get install zlib1g-dev
sudo apt-get install libfreetype6-dev
sudo apt-get install liblcms1-dev

Después desde Synaptic instale PIL seleccione el paquete

python-imaging 1.1.6-3 Python Imaging Library

En models.py agregue lo siguiente
image_book = models.ImageField(upload_to=’images/books’)

El siguiente articulo explica muy bien como funciona la ruta de ‘upload_to’

Quedando así mi MEDIA_ROOT

MEDIA_ROOT = ‘/home/dan5sanf/mysite/media’

Dentro de la carpeta ‘images’ upload_to crea la carpeta books donde guarda las imágenes que levanta.

En el template siendo ‘results’ la variable que contiene una consulta a la base de datos utilizo el campo ‘image_book’ de la siguiente manera:

{% for book in results %}

<img src="http://localhost:8000/site_media/{{ book.image_book}}" alt="" /

Si uno pone en el template {{ book.image_book }} vera que lo que muestra es una ruta hacia una imagen ('images/book/imagen.png') que al parecer es lo que nos devuelve el campo ImageField, una ruta hacia una imagen determinada.

Todo esto puede verse funcionando en el proyecto webookstore donde fue usado.

Contenidos estáticos

css

Django version 1.0 final
Dando mis primeros pasos con Django, para agregar los css hice lo siguiente; leí la documentación oficial que dice que Django no sirve archivos estáticos como imágenes, hojas de estilo o videos. Deja este trabajo para el servidor web que usted elija.
El razonamiento es que los servidores web estándar, como por ejemplo Apache, lighttpd y Cherokee, son mucho más ajustados para servir archivos estáticos en el marco de la aplicación Web.
Con eso dicho, Django es compatible con archivos estáticos durante el desarrollo. Usted puede utilizar el django.views.static.serve () para servir a los archivos multimedia.
El uso de este método es ineficiente e inseguro. No use esto en un entorno de producción. Utilice esto sólo para el desarrollo.
Para obtener información sobre servir archivos estáticos en un entorno de producción de Apache, consulte la documentación de mod_python.

Como hacerlo

Creo la carpeta ‘media’ dentro de mi proyecto ‘mysite’, dentro de ‘media’ creo las carpetas ‘css’ e ‘images’.
Agregamos en el archivo urls.py la siguiente entrada:

(r’^site_media/(?P.*)$’, ‘django.views.static.serve’,
{‘document_root’: ‘/home/dan5sanf/mysite/media’}),

Donde ‘/home/dan5sanf/mysite/media’ es la ruta absoluta con sintaxis de punto hacia la carpeta ‘media’ donde se encuentran los contenidos estáticos.

Se puede mejorar esto haciendo una entrada en el archivo de configuración y utilizar el valor de ajuste allí. Eso le permitirá a usted y otros desarrolladores que trabajan en el código cambiar fácilmente el valor según sea necesario.
Para eso en el archivo urls.py importamos settings.py

from django.conf import settings

Cambiamos la entrada anterior a:

(r’^site_media/(?P.*)$’, ‘django.views.static.serve’,
{‘document_root’: settings.STATIC_DOC_ROOT}),

Agregamos la ruta a ‘media’ en la variable STATIC_DOC_ROOT del archivo settings.py

STATIC_DOC_ROOT = ‘/home/dan5sanf/mysite/media’

link

En nuestra plantilla base.html el link presenta la entrada a urls.py a travéz de ‘site_media’ que nos redirige a la carpeta ‘media’ y desde allí la ruta al archivo que deseamos usar (‘/css/layout.css’).

href=’http://localhost:8000/site_media/css/layout.css’/>

Para agregar una imagen en la página es similar, suponiendo que la imagen se llama ‘logo.gif’ que esta en la carpeta ‘images’ dentro de la carpeta ‘media’ el enlace queda así:

img src=”site_media/images/logo.gif” alt=”" title=”" border=”0″ />

Esto nos permitirá usar estilo e imágenes en nuestra página html usando Django.

Todo esto puede verse funcionando en el proyecto webookstore donde fue usado.

relaxtives


Este es nuestro primer proyecto colaborativo. Somos estudiantes de un curso de programación en la Escuela de Oficios San Cayetano de Carapachay. Estamos desarrollando esta aplicación que servirá como respaldo a una institución de Beccar. La idea es cargar todos los alumnos de una escuela y relacionar los familiares. Elegimos hacerlo en wxPython con una base de datos MySQL. Para hacer la GUI usamos wxGlade, un lindo ayudante para la siempre tediosa tarea de diseñar las ventanas. Luego usamos Geany para tocar el código “a mano”.

Mi trabajo

Mi equipo esta formado por Hernan Montero y yo, nos toco realizar los formularios de Ingreso de datos y Modificación de datos. Las entradas del blog de la categoría wxPython son aspectos del diseño que me parecieron interesante mostrar

En ingreso de datos la logica de la aplicacion es sencilla; se pide los datos del alumno y se ingresan a la base de datos.
La parte mas elavorada es la grilla de la isquierda que agrega filas de acuerdo a la nesecidad del alumno.
Además tiene la caracteristica de tener cada celda de la grilla un ComboBox adentro con los monbres de los alumnos sacados de la base de datos y una lista con los parentezcos más comunes.

Modificar datos es mucho mas elaborado por abrir el formulario con todos los datos cargados que se desean modificar.

La lógica es la siguiente: se abre una ventana de busqueda, una vez localizado el alumno se carga los datos de este en el formulario, se modifican y se vuelven a ingresar a la base de datos.





Sitio web de relaxtives: http://code.google.com/p/relaxtives/

wx.Frame cambio de estilo

Al crear una wx.Frame,

class Frame(wx.Frame):
    def __init__(self, *args, **kwds):
        #MyFrame.__init__
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)

esta tendra el estilo wx.DEFAULT_FRAME_STYLE.
Pantallazo-Ventana Default
Este es una suma de estilos basicos: wx.MAXIMIZE_BOX | wx.MINIMIZE_BOX | wx.RESIZE_BORDER |wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX.
Para cambiar un estilo individual en una composición de estilo se usa el operador or ‘^’.
Necesito crear una ventana basada en el estilo default pero que no pueda cambiar su tamaño.
Para ello al estilo default le quito maximizar , minimizar y que no sea redimencionable la composición quedaría asi:
kwds["style"]=wx.DEFAULT_FRAME_STYLE^(wx.MINIMIZE_BOX|wx.MAXIMIZE_BOX |wx.RESIZE_BORDER))
Esto permitiría ver una ventana de este tipo:
Pantallazo-Relaxtives - Busqueda

Grid ComboBox MySQL


Hacer lista con consulta a db


Cambio del diseño; como los datos de la primera columna están en la base de datos (apellido, nombre y documento) se decidió colocar dentro de la grilla un combobox donde seleccionar estos datos del alumno.
La segunda columna de la grilla quedo igual, con un ComboBox dentro.
Para hacer esto se conecta a la db y se hace la consulta.


tChoiceEditor = wx.grid.GridCellChoiceEditor(['Padre ', 'Madre','Tio/a ','Primo/a','Hermano/a', 'Madrina', 'Padrino','Vecino/a'] , allowOthers=True) c.execute('''select apellidos, nombres, documento from alumnos order by apellidos''') q = c.fetchall() c.close()

Luego se crea una lista vacia ‘lista’, se recorre la variable q, que tiene los datos del fetchall a la db con un for buscando por el indice de q(q[0]) cada dato en la lista.


lista = [] for i in q: lista.append(i[0]+" "+ i[1]+" "+ i[2])

Se carga a la lista que luego va a usar el tChoiceEditor2 para mostrar en el ComboBox que esta dentro de la grilla.


tChoiceEditor2 = wx.grid.GridCellChoiceEditor(lista, allowOthers=True) #Asignar a los editores de la célula la fila y la columna. self.grid_parientes.SetCellEditor(0, 1, tChoiceEditor) self.grid_parientes.SetCellEditor(0, 0, tChoiceEditor2) #lista # Mostrar el tercer elemento de la lista en la celda ChoiceEditor #en este caso esta vacia, asi que no aparecera nada self.grid_parientes.SetCellValue(0, 1, self.grid_parientes.list[0][5])

El código completo y funcional de este formulario se llama ingreso_datos.py y es parte del proyecto relaxtives.
Pantallazo-Ingreso de datos

Seguir

Get every new post delivered to your Inbox.