Tôi có một vùng vẽ (chúng thực sự là bề mặt cairo, nhưng tôi không nghĩ nó quan trọng quá nhiều) trong một cửa sổ cuộn, và tôi muốn làm mới các bản vẽ. Tuy nhiên, khi tôi vẽ lại hình ảnh, chúng không được hiển thị cho đến khi tôi cuộn cửa sổ lên và xuống. Sau đó các số liệu là chính xác, vì vậy tôi phải kết luận rằng bản vẽ thường trình là chính xác. Tôi cũng đã bao gồm một sốvùng vẽ làm mới trong gtk
while Gtk.events_pending():
Gtk.main_iteration()
lặp lại để chờ tất cả các thao tác đang chờ xử lý, nhưng điều đó không giải quyết được sự cố. Ai đó có thể chỉ ra cho tôi những gì khác là mất tích?
Cảm ơn,
v923z
OK, vì vậy các khối lớn của mã này. Thứ nhất, một lớp học để định dạng vùng vẽ lên đó tôi sẽ vẽ (lưu ý rằng cơ thể không được thụt vào đúng Tôi không biết làm thế nào để thụt mảnh lớn của mã ở đây!):
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
Tiếp theo, điểm mà tôi thực sự tạo ra khu vực vẽ. viewport_preview là một khung nhìn được tạo trong 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
Sau đó, chức năng sẽ vẽ bản xem trước. Điều này thực sự chỉ là một wrapper cho các chức năng tiếp theo, và tôi cần thiết này chỉ vì nếu tôi xóa một mục trong xem trước, sau đó tôi phải xử lý trường hợp đó. Tôi tin rằng, vòng lặp while ở phần cuối của hàm này là không cần thiết, vì nó sẽ ở cuối của phần tiếp theo.
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()
Cuối cùng, chức năng vẽ bản thân:
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()
Tôi nghĩ đó là về nó.
Cảm ơn bạn đã trả lời! Thật không may, điều đó dường như không giải quyết được vấn đề. Trong thực tế, tôi đã có gtk.gdk.Window.invalidate_rect tất cả cùng, và nó là sự thật rằng nếu tôi rời khỏi đó ra sau đó vải không được cập nhật ở tất cả. Những gì tôi thấy khá lạ là thói quen vẽ của tôi vẽ màu trắng vải và sau đó vẽ các dòng trên đó, và bức tranh luôn được thực hiện, nhưng các dòng được hiển thị chỉ khi tôi cuộn các cửa sổ cuộn. Vì vậy, có vẻ như tiện ích con được cập nhật ít nhất một lần. – v923z
@ v923z: Ah ok! Nó thực sự có vẻ giống như một trường hợp thiếu sự kiện phơi bày! Có âm thanh lạ mặc dù ... bạn đang cập nhật canvas trong expose sự kiện gọi lại tôi presume & canvas đang được cập nhật mong đợi cho một vài dòng bản vẽ mất tích, là như vậy? Nếu có thể, bạn có thể đăng một vài đoạn mã ... chúng tôi có thể cố gắng giúp đỡ –
Cảm ơn bạn đã phản hồi! Tôi đã cập nhật bài đăng gốc của mình. – v923z