Pregunta

Estoy empezando a utilizar PyCairo, y me encontré con el siguiente error interesante. El programa de escritura que crea una ventana GTK sencilla, dibuja un rectángulo en él, y luego tiene una devolución de llamada para dibujar una línea aleatoria en cualquier tipo de entrada del teclado. Sin embargo, parece que con cada entrada de teclado, tengo que crear un nuevo contexto, o me sale un error en el momento en que el programa reciba primera entrada de teclado (en concreto, en la línea .stroke ()). El error es como sigue, si es importante. 'BadDrawable (Pixmap inválida o parámetro de ventana)'. (Los detalles: serial 230 error_code 9 request_code 53 minor_code 0)

#! /usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk, gobject, cairo, math, random
# Create a GTK+ widget on which we will draw using Cairo
class Screen(gtk.DrawingArea):
# Draw in response to an expose-event
  __gsignals__ = { "expose-event": "override" }

  # Handle the expose-event by drawing
  def do_expose_event(self, event):
    # Create the cairo context
    self.cr = self.window.cairo_create()
    # Restrict Cairo to the exposed area; avoid extra work
    self.cr.rectangle(event.area.x, event.area.y, event.area.width, event.area.height)
    self.cr.clip()

    self.draw(*self.window.get_size())

  def key_press_event(self, *args):
    # print args
    self.cr = self.window.cairo_create() # This is the line I have to add
    # in order to make this function not throw the error. Note that cr is only
    # given as attribute of self in order to stop it going out of scope when this line
    # doesn't exist
    self.cr.set_source_rgb(random.random(), random.random(), random.random())
    self.cr.move_to(*[z/2.0 for z in self.window.get_size()])
    self.cr.line_to(*[z*random.random() for z in self.window.get_size()])
    self.cr.stroke()

  def draw(self, width, height):
    # Fill the background with gray
    self.cr.set_source_rgb(.5,.5,.5)
    self.cr.rectangle(0, 0, width,height)
    self.cr.fill()

    self.cr.set_source_rgb(1,0,0)
    self.cr.arc(width/2.0, height/2.0, min(width,height)/2.0 - 20.0, 0.0, 2.0*math.pi)
    self.cr.stroke()

#create a gtk window, attach to exit button, and whatever is passed as arg becomes the body of the window. AWESOME
def run(Widget):
  window = gtk.Window()
  widget = Widget()
  window.connect("delete-event", gtk.main_quit)
  window.connect('key-press-event',widget.key_press_event)
  widget.show()
  window.add(widget)
  window.present()
  gtk.main()

if __name__ == "__main__":
  run(Screen)

Gracias por su ayuda!

(Actualización: Yo estaba jugando, y me di cuenta de lo siguiente:? Cuando se cambio el tamaño de la ventana, todos los objetos nuevos que se han añadido se eliminan (o al menos no aparecen ya))

¿Fue útil?

Solución

dibujos

El Cairo no persisten en absoluto. (Es mejor no es pensar en ellos como "objetos" -. No es como una biblioteca de lona donde se puede moverlos o transformarlos después de haberlos dibujado) Hay que hacer todo el dibujo en el manejador de exponer, o muestren, en la que han descubierto, desaparecen cada vez que la ventana se vuelve a dibujar.

El Cairo contexto no persisten debido a la doble buffer: ver el nota en el documentación C, que por desgracia no pude encontrar en cualquier parte de la documentación de PyGTK.

En el código anterior, se debe generar las coordenadas y el color de su línea de azar en el controlador de pulsación de tecla y guardarlos en una matriz. Luego, en el controlador de exponer, dibujar cada línea de la matriz en orden.

Otros consejos

, mientras que usted tiene que crear el contexto en cada carrera, se puede lograr la persistencia que busca mediante la desactivación del doble buffer del widget.

he aquí un ejemplo usando la biblioteca de gráficos de hámster que simplemente lo siguiente:

https://github.com/projecthamster/experiments/blob/master/ many_lines.py

Muchos sabores de persistencia para discutir:

Dibujos en algunos superficies no persisten: GUI superficies. Usted debe volver a dibujar en la devolución de llamada exponer.

objetos PyCairo no debe ser tratado como objetos persistentes, sólo como una interfaz para funciones de la biblioteca Cairo en C.

Los contenidos (caminos y rellenos) de contextos Cairo no persisten más allá de un accidente cerebrovascular () o de relleno () operación.

Un marco para una superficie de interfaz gráfica de usuario no persisten entre exponer eventos (debido a la doble buffer?) (No sé si persiste un contexto de otras superficies, es decir, dispositivos). Así que no se puede utilizar un contexto de Cairo almacenar los atributos de una ventana (una ventana a un modelo de documento es decir, en coordenadas de usuario.)

Visual persistencia es la tendencia del ojo humano para ver la luz después de que haya cesado. Los fantasmas y el parpadeo son sus síntomas en la animación o vídeo. Desactivación de doble buffer le permite ver las cosas tal como están redactados, que es, lo que permite la animación dentro de un evento de exposición (la simulación de los síntomas de la persistencia visual.) Desactivación de doble búfer no tiene un contexto en una superficie de interfaz gráfica de usuario persistente entre exponer eventos.

La persistencia de la memoria es la verdadera ur persistencia, o debería decir surrealista.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top