11
votes

Pourquoi mon programme Simple Python GTK + CAIRO fonctionne-t-il si lentement / bondeusement?

Mon programme dessine des cercles en mouvement sur la fenêtre. Je pense que je dois manquer un concept de base GTK / Caire parce qu'il semble courir trop lentement / bégayante pour ce que je fais. Des idées? Merci pour toute aide!

#!/usr/bin/python

import gtk
import gtk.gdk as gdk
import math
import random
import gobject

# The number of circles and the window size.
num = 128
size = 512

# Initialize circle coordinates and velocities.
x = []
y = []
xv = []
yv = []
for i in range(num):
    x.append(random.randint(0, size))
    y.append(random.randint(0, size))
    xv.append(random.randint(-4, 4))
    yv.append(random.randint(-4, 4))


# Draw the circles and update their positions.
def expose(*args):
    cr = darea.window.cairo_create()
    cr.set_line_width(4)
    for i in range(num):
        cr.set_source_rgb(1, 0, 0)
        cr.arc(x[i], y[i], 8, 0, 2 * math.pi)
        cr.stroke_preserve()
        cr.set_source_rgb(1, 1, 1)
        cr.fill()
        x[i] += xv[i]
        y[i] += yv[i]
        if x[i] > size or x[i] < 0:
            xv[i] = -xv[i]
        if y[i] > size or y[i] < 0:
            yv[i] = -yv[i]


# Self-evident?
def timeout():
    darea.queue_draw()
    return True


# Initialize the window.
window = gtk.Window()
window.resize(size, size)
window.connect("destroy", gtk.main_quit)
darea = gtk.DrawingArea()
darea.connect("expose-event", expose)
window.add(darea)
window.show_all()


# Self-evident?
gobject.idle_add(timeout)
gtk.main()


1 commentaires

Beau programme! J'essaierais de coloriser au hasard les boules pour faire un peu de bonbons pour les yeux; o)


3 Réponses :


2
votes

Je ne vois rien de fondamentalement mal avec votre code. Pour réduire le problème, j'ai essayé une approche différente qui peut être minime plus rapide, mais la différence est presque négligeable: xxx

aussi, déshabillant DradingArea.Draw () avec un talon ne fait aucune différence majeure.

J'essayerais probablement la liste de diffusion du Caire ou regarder l'encombrement ou le pygame pour dessiner un grand nombre d'éléments à l'écran.


0 commentaires

12
votes

Un des problèmes est que vous dessinez à nouveau le même objet de base. Je ne suis pas sûr du comportement de la mémoire tampon GTK +, mais gardez également à l'esprit que les appels de fonction de base incontent un coût en Python. J'ai ajouté un compteur de cadre à votre programme, et moi avec votre code, j'ai eu environ 30fps max.

Il y a plusieurs choses que vous pouvez faire, par exemple, composez des chemins plus importants avant d'appeler une méthode de remplissage ou de course (c'est-à-dire tous les arcs dans un seul appel). Une autre solution, qui est considérablement plus rapide consiste à composer votre balle dans un tampon hors écran, puis à la peindre à l'écran à l'écran à plusieurs reprises: xxx

ceci donne environ 273 fps sur mon machine. Pour cette raison, vous devriez penser à utiliser gobject.timeout_add plutôt que idle_add .


3 commentaires

Y a-t-il un moyen d'utiliser cette méthode plus rapide tout en pouvant régler la couleur du cercle au tirage? Merci!


Rien que je connaisse (sans faire beaucoup de recherche), vous devrez créer plusieurs images à l'avance.


Le véritable goulot d'étranglement au Caire est la génération de masque. Vous pouvez donc la créer à l'avance et remplir plus de fois avec différentes sources. C'est le thread du Caire pertinent (Détails de la mise en œuvre de C bien-être): . Cairographics.org/archives/cairs/2009-OCTOBER/018243.H TML



0
votes

J'ai le même problème dans le programme a été écrit sur C #. Avant de quitter expose événement, essayez d'écrire cr.dispose () .


0 commentaires