Tengo un montón de áreas de dibujo (en realidad son superficies de cairo, pero no creo que importe demasiado) en una ventana desplazada, y me gustaría actualizar los dibujos. Sin embargo, cuando vuelvo a dibujar las imágenes, no se muestran hasta que muevo la ventana hacia arriba y hacia abajo. Después de eso, las cifras son correctas, así que tengo que concluir que la rutina de dibujo en sí es correcta. También he incluido unactualizar área de dibujo en gtk
while Gtk.events_pending():
Gtk.main_iteration()
loop para esperar todas las operaciones pendientes, pero eso no resuelve el problema. ¿Podría alguien indicarme qué más falta?
Gracias,
v923z
OK, por lo que los trozos más grandes del código. En primer lugar, una clase que define el área de un dibujo sobre el que voy a pintar (tenga en cuenta que el cuerpo no tiene sangría correctamente No sé cómo se va a sangrar códigos muy grandes aquí!):
class Preview:
def __init__(self):
self.frame = Gtk.Frame()
self.frame.set_shadow_type(Gtk.ShadowType.IN)
self.frame.show()
self.da = Gtk.DrawingArea()
self.da.set_size_request(200, 300)
self.da.connect('configure-event', self.configure_event)
self.da.connect('draw', self.on_draw)
self.frame.add(self.da)
self.da.show()
def configure_event(self, da, event):
allocation = da.get_allocation()
self.surface = da.get_window().create_similar_surface(cairo.CONTENT_COLOR,
allocation.width,
allocation.height)
cairo_ctx = cairo.Context(self.surface)
cairo_ctx.set_source_rgb(1, 1, 1)
cairo_ctx.paint()
return True
def on_draw(self, da, cairo_ctx):
cairo_ctx.set_source_surface(self.surface, 0, 0)
cairo_ctx.paint()
return True
pass
A continuación, el punto donde realmente creo el área de dibujo. viewport_preview es una ventana gráfica creada en glade.
self.previews = []
self.widget('viewport_preview').remove(self.vbox_preview)
self.vbox_preview = Gtk.VBox(homogeneous=False, spacing=8)
self.widget('viewport_preview').add(self.vbox_preview)
self.vbox_preview.show()
for page in self.pages:
preview = Preview()
self.vbox_preview.pack_start(preview.frame, False, False, 10)
self.previews.append(preview)
while Gtk.events_pending():
Gtk.main_iteration()
self.draw_preview(None)
return True
Luego, la función que dibuja las vistas previas. Esto es realmente solo un contenedor para la siguiente función, y lo necesitaba solo porque si eliminé una entrada en las vistas previas, entonces tengo que manejar ese caso. Creo que el ciclo while al final de esta función no es necesario, ya que de todos modos estará al final de la siguiente.
def draw_preview(self, counter=None):
if counter is not None:
self.vbox_preview.remove(self.previews[counter].frame)
self.previews.pop(counter)
self.pages.pop(counter)
self.vbox_preview.show()
while Gtk.events_pending():
Gtk.main_iteration()
for i in range(len(self.pages)):
self.draw_note(self.previews[i].da, self.previews[i].surface, self.pages[i])
while Gtk.events_pending():
Gtk.main_iteration()
Por último, la función de dibujo en sí:
def draw_note(self, widget, surface, page):
list_pos = '%d/%d'%(self.page + 1, len(self.pages))
self.widget('label_status').set_text(list_pos)
cairo_ctx = cairo.Context(surface)
cairo_ctx.set_source_rgb(page.background[0], page.background[1], page.background[2])
cairo_ctx.paint()
width, height = widget.get_size_request()
xmin, xmax, ymin, ymax = fujitsu.page_size(page)
factor = min(height/(2.0 * self.margin + ymax - ymin), width/(2.0 * self.margin + xmax - xmin))
factor *= 0.8
page.scale = factor
value = self.widget('adjustment_smooth').get_value()
#print value
for pen in page.pagecontent:
x = self.margin + pen.path[0][0] - xmin
y = self.margin + pen.path[0][1] - ymin
cairo_ctx.move_to(x * factor, y * factor)
if self.widget('checkbutton_smooth').get_active() == False:
[cairo_ctx.line_to((self.margin + x - xmin) * factor,
(self.margin + y - ymin) * factor) for x, y in pen.path]
else:
bezier_curve = bezier.expand_coords(pen.path, value)
x = self.margin + bezier_curve[0][0][0] - xmin
y = self.margin + bezier_curve[0][0][1] - ymin
cairo_ctx.move_to(x * factor, y * factor)
[cairo_ctx.curve_to((self.margin + control[1][0] - xmin) * factor,
(self.margin + control[1][1] - ymin) * factor,
(self.margin + control[2][0] - xmin) * factor,
(self.margin + control[2][1] - ymin) * factor,
(self.margin + control[3][0] - xmin) * factor,
(self.margin + control[3][1] - ymin) * factor)
for control in bezier_curve]
cairo_ctx.set_line_width(pen.thickness * self.zoom_factor)
cairo_ctx.set_source_rgba(pen.colour[0], pen.colour[1], pen.colour[2], pen.colour[3])
cairo_ctx.stroke()
cairo_ctx.rectangle(0, height * 0.96, width, height)
cairo_ctx.set_source_rgba(page.banner_text[0][0], page.banner_text[0][1], page.banner_text[0][2], page.banner_text[0][3])
cairo_ctx.fill()
cairo_ctx.move_to(width * 0.05, height * 0.99)
cairo_ctx.show_text(self.filename + ' ' + list_pos)
cairo_ctx.set_font_size(self.zoom_factor * 10.0)
xbearing, ybearing, twidth, theight, xadvance, yadvance = (cairo_ctx.text_extents(page.banner_text[3]))
cairo_ctx.move_to(width - 1.03 * twidth, height * 0.99)
cairo_ctx.show_text(page.banner_text[3])
cairo_ctx.set_source_rgba(0, 0, 0.9, 0.90)
cairo_ctx.stroke()
rect = widget.get_allocation()
widget.get_window().invalidate_rect(rect, False)
while Gtk.events_pending():
Gtk.main_iteration()
creo que eso es todo.
Gracias por la respuesta! Desafortunadamente, eso no parece resolver el problema. De hecho, he tenido gtk.gdk.Window.invalidate_rect todo el tiempo, y es cierto que si lo dejo, el lienzo no se actualiza en absoluto. Lo que encuentro bastante extraño es que mi rutina de dibujo pinta el lienzo en blanco y luego dibuja líneas sobre él, y la pintura siempre está lista, pero las líneas solo se muestran si muevo las ventanas desplazadas. Por lo tanto, parece que el widget se actualiza al menos una vez. – v923z
@ v923z: ¡Ah está bien! ¡Realmente parecía un caso de eventos de exposición perdidos! Suena extraño, sin embargo ... estás actualizando el lienzo en exponer devoluciones de eventos de eventos. Supongo que & canvas se está actualizando. Espera unos pocos dibujos de líneas faltantes, ¿es así? Si es posible, tal vez podría publicar algunos bits de código ... podríamos intentar ayudar –
¡Gracias por los comentarios! He actualizado mi publicación original. – v923z