[Python-es] borde de celda wx grid

Oswaldo Hernández listas en soft-com.es
Lun Feb 14 10:39:34 CET 2011


El 13/02/2011 11:38, damufo escribió:
...
>
> A partir del ejemplo de la demo de wxpython, he logrado dibujar los
> bordes de una celda, aunque no comprendo todo el código ya que para mi
> nivel de conocimiento me pierdo, fuí logrando cosas por ensaya y error.
>

Correcto, pero el wx.Grid es un objeto muy potente y complejo, te 
recomiendo le dediques tiempo a estudiar su clases y funcionamiento.

> Al grano, resulta que tengo una clase que hereda de Grid.PyGridCellRenderer
> esta es la que dibuja la celda especial (en mi caso quiero que le ponga
> bordes), con el método Draw() en este caso pinta bordes, además quiero
> que trate tambien celdas combinadas.
>
> Lo que me gustaría es que antes de pintar los bordes pintase la celda
> normal, y despues sobre ella pintase dichos bordes. Por ejemplo si por
> defecto en alineación vertical tengo centrado quiero que así ponga el
> texto.
> Para ello en el mi calse especial sólo he puesto el código que dibuja
> los bordes y el caso es que tal como esta lo de dentro se queda sin
> rellenar.

Cuando creas tu propio renderizador el grid asume que tu te vas a 
encargar de todo, para eso te pasa todo lo que necesitas en el metodo 
Draw():

- grid.GetCellValue(row, col) te daria el valor de la celda
- attr es una instancia de GridCellAttr [1], usandola puedes saber la 
alineación, fuente, colores a utilizar, etc.
- dc es el el DeviceContext sobre el que pintar [2]
- rect te informa del tamaño actual de la celda
- isSelected te indica si la celda esta en modo selección para que la 
pintes del modo adecuado

>
> Si no me equivoco este método Draw() está sobrecargando el Draw() por
> defecto, hay forma de que cuando llame mi método Draw() "modificado",
> dentro de el llame antes al método Draw() por defecto (clase de la que
> hereda) y despues realice las modificaciones que he puesto en mi método
> sobrecargado?
>
> Espero que se entienda. (primero pinta como si de una celda normal se
> tratase y despues por encima pon estas líneas)
>

Con clases "normales" harías una derivación del renderizador 
predeterminado (GridCellStringRenderer) para hacer lo que tu quieres:

class CellRenderer(Grid.GridCellStringRenderer):
     def Draw(self, grid, attr, dc, rect, row, col, isSelected):
         # Ejecutar GridCellStringRenderer
         super(CellRenderer, self).Draw(grid, attr, dc, rect, row, col, 
isSelected)
	# Parte personalizada
         dc.SetPen( wx.Pen(wx.Colour( 255, 0, 0 ) , 1, wx.SOLID))
         dc.DrawLine( rect.x + rect.width-1, rect.y, rect.x + 
rect.width-1, rect.y + rect.height)
	...

Pero si lo pruebas verás que eso no funciona.

Haciendo alguna prueba he descubierto un truco que en principio parece 
que funciona, pero si utilizas, hazlo con precaución, ya que no lo he 
visto documentado en ningún sitio y desconozco si puede tener algún 
efecto secundario:

class CellRenderer(Grid.PyGridCellRenderer):
     def Draw(self, grid, attr, dc, rect, row, col, isSelected):
         # ejecuar renderizador de strings
         Grid.GridCellStringRenderer().Draw(grid, attr, dc, rect, row, 
col, isSelected)
	# Agregar parte personalizada
	dc.SetPen( wx.Pen(wx.Colour( 255, 0, 0 ) , 1, wx.SOLID))
	dc.DrawLine( rect.x + rect.width-1, rect.y, rect.x + rect.width-1, 
rect.y + rect.height)
	...


Un Saludo



[1] <http://www.wxpython.org/docs/api/wx.grid.GridCellAttr-class.html>
[2] <http://www.wxpython.org/docs/api/wx.DC-class.html>

-- 
Oswaldo Hernández


Más información sobre la lista de distribución Python-es