Вопрос

Я создаю сетевой аниматор (похожий на nam, если вы использовали его раньше).

По сути, у меня есть узлы, представленные в виде маленьких точек в области рисования GTK +, и я обновляю позиции этих узлов и перерисовываю область рисования в цикле.

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

Как, по-вашему, я могу наилучшим образом решить эту проблему?Должен ли я предварительно отрисовывать кадры в Pixbufs?Есть ли лучшее решение?

Вот мой текущий код рисования (с использованием PyGTK):

rect  = self.drawing_area.get_allocation()
style = self.drawing_area.get_style()

pos   = [n.position_at(self.t) for n in self.nodes]

self.drawing_area.window.draw_rectangle(style.bg_gc[gtk.STATE_NORMAL], True,
                                        0, 0, rect.width, rect.height)

for p in pos:
    self.drawing_area.window.draw_arc(style.fg_gc[gtk.STATE_NORMAL], True,
                                      rect.width  * (p.x / 2400.0) - NODE_SIZE/2,
                                      rect.height * (p.y / 2400.0) - NODE_SIZE/2,
                                      NODE_SIZE, NODE_SIZE,
                                      0, 64 * 360)

где self.t это текущее время, которое увеличивается в цикле.

Это было полезно?

Решение

Я изменил свой код, чтобы отобразить рамки на пиксельном изображении, и заменил область рисования изображением.

В то время как это решило проблему мерцания, теперь загрузка процессора достигла пика.Анимация по-прежнему довольно быстрая, но я не думаю, что этот метод масштабируемый.

Думаю, пришло время для некоторой оптимизации.

Обновить: Оказывается, использование expose-event с изображением было не такой уж хорошей идеей.Загрузка процессора вернулась к норме.

Другие советы

Что касается обработки событий expose, ознакомьтесь с первым абзацем, посвященным анимации с Cairo + Gtk:P

Многопоточная анимация с использованием Cairo и GTK+
Сложная анимация с помощью cairo и GTK + может привести к зависанию интерфейса.Это происходит потому, что поток gtk_main() выполняется в одном цикле.Итак, если ваш do_draw() функция реализует сложную команду рисования, и она вызывается из потока gtk_main() (скажем, с помощью on_window_expose_event() функция), остальная часть вашего кода gtk будет заблокирована до тех пор, пока функция do_draw() не завершится.Следовательно, пункты меню, щелчки мышью и даже события кнопки закрытия будут обрабатываться медленно, и ваш интерфейс будет казаться запаздывающим.

Одно из решений состоит в том, чтобы передать все процессороемкие отрисовки в отдельный поток, тем самым освободив поток gtk_main() для реагирования на события.

http://cairographics.org/threaded_animation_with_cairo/

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top