2015-07-19 7 views
1

Я использую Каир с gi.repository.Gtk.DrawingArea, и мне нужно обрабатывать два различных вида событий:queue_draw_area с конкретным обработчиком?

  • Обновление резюме строки (draw_summary())
  • Нарисуйте новую точку (draw_dot()

В идеале я сделал бы недействительным только небольшую область (например, вертикальную полосу области рисования), когда мне нужно сделать draw_dot(), и я бы сделал недействительным другую область, когда хочу draw_dummary(). Я мог перерисовывать весь регион каждый раз, но это будет дорого и Я бы предпочел только обновить места, которые в ней нуждаются.

Насколько я могу судить, мой единственный доступный механизм запуска является вызов:

 plot.queue_draw_area 

- но этот вызов в свою очередь, подключен к draw события через:

 self.plot_area.connect("draw", self.handle_draw) 

. .. Это означает, что у меня нет способа разместить draw_dot отдельно от звонка draw_summary. Когда я звоню queue_draw_area, все, что я могу сделать, это вызвать моего одного обработчика. Существует ли стандартный шаблон для разбиения операции рисования на отдельные функции, которые могут быть поставлены в очередь независимо?

+0

Есть две вещи, которые вы можете сделать: вы можете либо заблокировать отдельные соединения с помощью 'g_signal_handler_block()' и 'g_signal_handler_unblock()' (или их эквиваленты Python), либо получить область отсечения контекста cairo в ваших обработчиках рисования и ничего не делать, если вы не будете рисовать там все равно (подробности см. в документации GtkWidget :: draw). – andlabs

+0

Спасибо - это полезно, но это все равно означает, что мой обратный вызов рисунка должен эффективно выполнять всю логику рисования всего, чтобы выяснить (а не сказать), какие операции нужно предпринять. Я ищу флип этой модели на голове (поскольку мой код, который вызывает недействительность, действительно знает, что должно произойти). – Bosh

ответ

1

Uhm. Как работает ваш рисунок? Я имею в виду, что GTK также может вызвать ваш обратный вызов по другим причинам, чем ваши внутренние перерисовки. Таким образом, вы создаете обратный вызов, чтобы иметь возможность обрабатывать полный перерисовку в любом случае.

Для вашей оптимизации: вы можете получить контекст клипа контекста cairo, чтобы выяснить, в какой части на самом деле нужно перерисовать. Функция в C равна cairo_clip_extents, чтобы получить ограничивающий прямоугольник и `cairo_copy_clip_rectangle_list ', чтобы получить список всех отдельных прямоугольников, которые являются частью клипа.