Ho un sacco di aree di disegno (in realtà sono superfici del cairo, ma non credo che importi troppo) in una finestra a scorrimento, e vorrei aggiornare i disegni. Tuttavia, quando ridisegno le immagini, esse non vengono visualizzate finché non faccio scorrere la finestra su e giù. Dopo che le cifre sono corrette, quindi devo concludere che la stessa routine di disegno è corretta. Ho anche incluso unorinfrescare l'area di disegno in gtk
while Gtk.events_pending():
Gtk.main_iteration()
loop per attendere tutte le operazioni in sospeso, ma ciò non risolve il problema. Qualcuno potrebbe indicarmi cos'altro manca?
Grazie,
v923z
OK, in modo che i grandi blocchi di codice. In primo luogo, una classe che definisce l'area di un disegno su cui ho intenzione di dipingere (si noti che il corpo non è rientrato correttamente non so come rientrare più grandi pezzi di codice qui!):
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
Avanti, il punto in cui effettivamente creo l'area di disegno. viewport_preview è una finestra creata in 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
Quindi la funzione che traccia le anteprime. Questo è davvero solo un wrapper per la prossima funzione, e avevo bisogno di questo solo perché se elimino una voce nelle anteprime, allora devo gestire quel caso. Credo che il ciclo while alla fine di questa funzione non sia necessario, poiché sarà comunque alla fine di quello successivo.
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()
Infine, la funzione disegno stesso:
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()
penso che su di esso.
Grazie per la risposta! Sfortunatamente, questo non sembra risolvere il problema. In effetti, ho sempre avuto gtk.gdk.Window.invalidate_rect, ed è vero che se lo lascio fuori la tela non viene affatto aggiornata. Quello che trovo piuttosto strano è che la mia routine di disegno dipinge la tela bianca e poi disegna linee su di essa, e il dipinto è sempre fatto, ma le linee sono mostrate solo se faccio scorrere le finestre a scorrimento. Quindi, sembra che il widget sia aggiornato almeno una volta. – v923z
@ v923z: Ah ok! Sembrava davvero un caso di eventi mancati di esposizione! Suona strano però ... stai aggiornando la tela nel richiamo dell'evento expose Suppongo che la tela sia in fase di aggiornamento aspettati per alcuni disegni di linee mancanti, è così? Se possibile forse potresti postare qualche pezzetto di codice ... potremmo provare ad aiutare –
Grazie per il feedback! Ho aggiornato il mio post originale. – v923z