Aventuras no Cairo

Alguns dias atrás comecei a mexer na muito falada (e que será adotada pelo Firefox) biblioteca de desenho vetorial Cairo, com o propósito de fazer um widget em PyGTK representando um heptágono cujos vértices pudessem ser movidos. Eventualmente passei um tempo aprendendo o básico até estancar num problema irritante, que pra variar tinha uma solução simples.

Heptágono

Para criar meu widget, chamado ValueWheel, precisei extender GtkDrawingArea e criar meus próprios métodos para interceptar alguns eventos, como “expose-event”, que acontece toda vez que uma janela, ou parte dela, precisa ser redesenhada. Quando clicava numa das bolinhas nos vértices e a arrastava, meu método que cuidava do “motion-notify-event” reposicionava a tal bolinha e redesenhava tudo. O grande problema é que esses redesenhos estavam muito lentos, com direito a piscada e tudo.

Bastante tempo depois, procurando no Google Code Search, descobri que o jeito certo de fazer a coisa não era ordenar o redesenho diretamente, e sim forçar a emissão do evento expose. Coloquei essas quatro linhas no método de movimento:

alloc = self.get_allocation()
rect = gtk.gdk.Rectangle(0, 0, alloc.width, alloc.height)
self.window.invalidate_rect(rect, True)
self.window.process_updates(True)

Era necessário apenas “invalidar” a área que foi redesenhada e avisar que um update era necessário, que magicamente o widget se redesenhou e sem piscar.

Aos interessados em Cairo eu recomendo:

E o código sobre o qual este post fala é esse: ValueWheel.py

6 pensamentos sobre “Aventuras no Cairo

  1. Olá Walter,
    Cairo não é difícil, mas tem algumas nuances, como paths por exemplo, que vão formando um caminho por tudo que é desenhado, e você tem ter o cuidado de fechar um caminho se quiser preenchê-lo com alguma cor. Mas tudo faz sentido e a api é bem clara, além de a aparência geral ser muito boa, especialmente quando o desenho é redimensionado, então compensa o aprendizado.
    Dá uma olhada nos exemplos pra ver algumas coisas possíveis:
    http://cairographics.org/samples/

    Está em C, mas a diferença pra Python é algo como:
    * CAIRO_OPERATOR_ADD para cairo.OPERATOR_ADD
    * cairo_set_source_rgb(context, 0,1,0); para context.set_source_rgb(0,1,0)

    E re-recomendo os tutoriais “Cairo Tutorial for Python Programmers” e “Cairo Tutorial for PyGTK Programmers”.

  2. Pingback: Sinais em PyGTK e Google Code Search « Head Like a Hole

  3. Pingback: TagGen, Gerador de Personagens para Tagmar 2 (ponto 2) « Head Like a Hole

  4. Pingback: CairoPlot - Plotting Graphics using Python and Cairo «

  5. Pingback: Sinais em PyGTK e Google Code Search « Head Like a Hole

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s