Плавная анимация с использованием GTK +
Вопрос
Я создаю сетевой аниматор (похожий на 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() для реагирования на события.