I have a bunch of drawing areas (they are actually cairo surfaces, but I donβt think it is too important) in a scrollable window, and I would like to update the drawings. However, when I redraw the images, they are not displayed until I scroll the window up and down. After that, the numbers are correct, so I must conclude that the drawing procedure itself is correct. I also included
while Gtk.events_pending(): Gtk.main_iteration()
to wait for all pending operations, but this does not solve the problem. Can someone point me to what is still missing?
Thanks,
v923z
OK, so big pieces of code. Firstly, the class that defines the drawing area I'm going to draw onto (note that the body is not indented correctly! I donβt know how indentation is more than code snippets here):
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
Next, the point where I actually create the drawing area. viewport_preview is a viewport created in a clearing.
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
The function then draws the previews. It really is just a wrapper for the next function, and I need it only because if I delete one entry in the previews, then I will have to handle this case. I believe the while loop at the end of this function is not needed, as it will be at the end of the next.
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()
Finally, the drawing function itself:
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()
I think about this.