Простая настройка для буфера пикселей Python + Cairo + GTK / GDK - PullRequest
2 голосов
/ 20 октября 2011

Для моей собственной пользы и, возможно, для использования в образовательных целях, я хотел бы создать API-интерфейс, похожий на pygame, для Python и Cairo. Но я не хочу, чтобы это было именно пигмеем. Вместо этого я хотел бы сделать его полустатической платформой для рисования, которая отображает одно или несколько изображений с использованием GTK / GDK, и я хотел бы подражать превосходным принципам API TiKZ (пакет из латекса). API PyGame неплох, но я не удовлетворен этим. Одна конкретная проблема заключается в том, что я хотел бы, чтобы пакет обрабатывал обновление окна, рисуя все в pixbuf (с Cairo), и автоматически перерисовывал pixbuf, когда окно открывается. Таким образом, конечному программисту не нужно беспокоиться об обновлении окна. На самом деле, конечному программисту не нужно писать отдельный класс или функцию или нечто большее, чем прямую последовательность строк кода, чтобы нарисовать улыбающееся лицо (скажем). Графическая библиотека также не должна содержать постоянно растущий список сохраненных объектов формы, как в TkInter. (По крайней мере, я надеюсь, что Каир не делает этого вопреки моим намерениям.)

Мне удалось нарисовать различные вещи в Pycairo с выводом в ImageMagick и Postscript. Так что я в порядке с самой Пикаиро.

К сожалению, документация по cairo / gtk / pycairo / pygtk, которую я нашел - я не знаю, для кого она написана, но не для меня. На данный момент я программист типа Project Euler, а не программист типа «5 передовых ультра-объектно-ориентированных API». Я хотел бы видеть четкое объяснение того, что делать, и / или четкий пример.


Хорошо, я принял один ответ, который был опубликован, потому что он был хотя бы немного полезным. Но здесь в двух словах это реальная точка. Дело в том, что GDK создает двойной буфер временный , когда вы рисуете вещи в GDK, включая использование Cairo. Ожидается, что когда вы обрабатываете событие expose, вы просто перерисовываете все. Но если у вас очень сложное изображение, это медленный процесс, особенно в Python. Поэтому было бы гораздо приятнее, если бы Cairo мог записывать в постоянный двойной буфер постоянный , а не во временный, и тогда этот постоянный двойной буфер был бы открыт с помощью GDK. Несколько разработчиков хотели решить эту проблему. Один из проектов, который, похоже, имеет какое-то решение, - это Google Chromium - вы когда-нибудь замечали, насколько велика экспозиция окон в Google Chrome, например в Linux? Поэтому я посмотрю на исходный код Chromium, чтобы узнать, смогу ли я сделать это легко.

Добавление: я вижу, что действительно перепутал проблему, обращаясь конкретно к "pixbufs". Меня не волнуют pixbufs (и я снова изменил название вопроса). Что меня действительно волнует, так это создание постоянного пиксельного массива с двойным буфером между Cairo и GTK / GDK вместо временного массива с двойным буфером. Кажется, что самый простой способ сделать это - сделать окно GTK поверхностью Каира, а двойной буфер - другой поверхностью Каира. Так как я попросил образец в моем вопросе, вот некоторые:

class Canvas(gtk.DrawingArea):
    def __init__(self):
        super(Canvas, self).__init__()
        self.connect("expose_event", self.expose)
        self.set_size_request(width,height)

    def expose(self, widget, event):
        cr = widget.window.cairo_create()
        cr.set_source_surface(mybuffer,0,0)
        cr.paint()

Еще одна сложная проблема, которая быстро возникла, заключается в том, что я хотел, чтобы это была среда рисования WYSISWYG, которая немедленно рисует то, что просит Python, - и может быть распространена на анимацию. Однако большинство примеров GTK не настроены таким образом: обработка событий откладывается до тех пор, пока я не вызову gtk.main(). (Или в Python я с удивлением обнаружил, что raw_input() также каким-то образом сбрасывает очередь событий GTK.) Я нашел хорошее объяснение , с примерами Python, альтернативы передаче управления событиями GTK. Самое простое и, возможно, единственное решение, которое я приму, это использовать его для очистки буфера событий всякий раз, когда вы захотите это сделать:

while gtk.events_pending(): gtk.main_iteration(False)

Есть еще одна вещь, которая мне понадобится, чтобы очистить буфер пикселей, а также буфер событий. Похоже, один из способов сделать это - window.queue_draw()

1 Ответ

2 голосов
/ 20 октября 2011

Поскольку это было слишком много для комментария, я добавил это как ответ.
Вопрос не совсем ясен.Вы хотите спросить, как использовать рисование в Каире для рисования на виджетах Gtk?Во-первых, нет ничего под названием GTK Pixbuf, я думаю, что вы имеете в виду GDK Pixbuf.Большая часть рисования в GTK выполняется на слое GDK .Если вы хотите узнать об управлении окнами, механизме рисования или манипулировании изображениями, вам следует изучить GDK для получения более подробной информации. Эти ссылки , надеюсь, помогут вам получить представление о взаимодействии cairo-gdk.Хотя мой опыт работы с привязками Python для GTK, GDK & Cairo нулевой, но я думаю, что Google предоставит вам некоторые хорошие ресурсы, если вы посмотрите пример gdk-cairo.
Надеюсь, это поможет хоть немного!

...