2010-06-28 4 views
3

Je souhaite déplacer automatiquement mon GTK_WINDOW sur l'écran. Actuellement, je l'ai dans une boucle draw/move, mais c'est terriblement saccadé. Je suis très nouveau dans la programmation GTK (et la programmation gui en général). Qu'est-ce que je rate?Animation de mouvement de fenêtre GTK?

+0

Personne ne veut me répondre. Sad panda: '( – jdizzle

+0

) Je ne sais pas non plus, je m'intéresse à ce que vous avez jusqu'ici, pourriez-vous aussi poster votre code? Cela peut aussi être une invitation pour que d'autres répondent/corrigent votre code – Benjamin

+0

PS: there peut être des informations sur http://macslow.thepimp.net/, voir par exemple http://www.youtube.com/watch?v=X8NoZ041RPA&NR=1 – Benjamin

Répondre

5

Vous n'avez pas indiqué quel type de chemin vous souhaitez que la fenêtre suive. Si le chemin est une simple fonction du temps - c'est-à-dire, si vous avez un moyen de calculer où vous voulez que la fenêtre soit à un moment donné - vous pouvez essayer la méthode illustrée dans le code suivant. Pour le menu assez simple de l'exemple, cela fonctionne bien sur mon système Linux et produit un mouvement assez fluide.

La clé de la méthode est qu'au lieu de déplacer la fenêtre d'une distance donnée par événement de minuterie, elle trouve l'heure actuelle et déplace la fenêtre à l'endroit où elle devrait être, à ce moment-là. Ainsi, la dérivée temporelle de la vitesse de déplacement doit être constante, ce qui évite les mouvements irréguliers ou saccadés même si les événements du temporisateur se produisent de manière irrégulière. (Comme indiqué dans g-timeout-add() description, l'irrégularité peut facilement se produire.)

Dans cet exemple, le chemin est à partir du coin supérieur gauche de la fenêtre en bas à gauche et en arrière, de manière répétée. La constante 'HalfTime' dans timerEvent() contrôle le temps nécessaire pour se déplacer d'un coin à l'autre. La constante 3 de l'appel g_timeout_add() définit l'intervalle de la minuterie à 0,003 seconde, soit environ 333 coups par seconde (MPS). (Vous pouvez essayer des taux plus raisonnables, tels que 20, 30, 40, etc MPS, j'ai utilisé le numéro 3 parce que je n'ai pas recherché g-timeout-add() avant de l'utiliser, et supposé que le délai était de quelques secondes, pour environ 33 MPS, plutôt que millisecondes, pour environ 333 MPS.) Si le contenu de votre fenêtre est assez complexe, moins de MPS sera pratique. En outre, j'ai essayé quelques taux plus lents et ai eu plus d'une impression de coup de bâton.

/* $Id: app12.c $ 
Re: animating position of a top-level Gtk window 
jiw July 2011 -- Offered without warranty under GPL v3 
terms per http://www.gnu.org/licenses/gpl.html */ 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <math.h> 
#include <gtk/gtk.h> 
typedef struct DATA { GTimer *timer; GtkWidget *window; int w, h; } 
    DataStruct; 

gboolean timerEvent(void *dataset) { 
    enum { HalfTime=8, CycTime=2*HalfTime }; 
    gulong micros; 
    DataStruct *data =dataset; 
    double t = fabs(fmod (g_timer_elapsed (data->timer, &micros), CycTime)); 
    int x = (t*data->w)/HalfTime, y = (t*data->h)/HalfTime; 
    gtk_window_move (GTK_WINDOW(data->window), 
     t<HalfTime? x : 2*data->w-x, t<HalfTime? y : 2*data->h-y); 
    return TRUE; /* Keep timeout running */ 
} 

int main(int argc, char **argv) { 
    GtkWidget *vbox, *b; 
    GdkScreen *gds; 
    DataStruct data; 
    data.timer = g_timer_new(); 
    gtk_init (&argc, &argv); 
    data.window = gtk_window_new (GTK_WINDOW_TOPLEVEL); 
    gtk_window_set_default_size (GTK_WINDOW(data.window), 200, 150); 
    g_signal_connect (G_OBJECT(data.window), "destroy", 
      G_CALLBACK(gtk_main_quit), NULL); 
    vbox = gtk_vbox_new (FALSE, 0); 
    gtk_container_add (GTK_CONTAINER(data.window), vbox); 
    b = gtk_button_new_with_label ("Click to Exit"); 
    gtk_box_pack_start (GTK_BOX(vbox), b, TRUE, TRUE, TRUE); 
    g_signal_connect (b, "clicked", G_CALLBACK(gtk_main_quit), NULL); 
    gtk_widget_show_all (data.window); 

    gds = gdk_screen_get_default(); /* Get pointer to screen */ 
    data.w = gdk_screen_get_width (gds); /* Find out screen width */ 
    data.h = gdk_screen_get_height (gds); /* Find out screen height */ 
    printf ("Screen size = %d by %d\n", data.w, data.h); fflush(stdout); 
    g_timeout_add(3, timerEvent, &data); /* Create .003 sec timer */ 
    gtk_main(); 
    return (0); 
} 
Questions connexes