GTK анимация движения окна? - PullRequest
3 голосов
/ 28 июня 2010

Я хочу переместить мой GTK_WINDOW по экрану автоматически.В настоящее время у меня это в цикле рисования / перемещения, но это ужасно изменчиво.Я очень новичок в программировании на GTK (и вообще на графическом программировании).Чего мне не хватает?

1 Ответ

5 голосов
/ 26 июля 2011

Вы не сказали, каким путем вы хотите, чтобы окно следовало. Если путь является некоторой простой функцией времени, то есть если у вас есть способ вычислить, где вы хотите, чтобы окно находилось в любой момент времени, вы можете попробовать метод, показанный в следующем коде. Для довольно простого меню в примере оно работает нормально в моей системе Linux и производит довольно плавное движение.

Ключом к методу является то, что вместо перемещения окна на заданное расстояние на событие таймера, он узнает текущее время и перемещает окно в то место, в котором он должен быть в это время. Таким образом, производная по времени от скорости движения должна быть постоянной, что позволяет избежать прерывистого или прерывистого движения, даже если события таймера происходят нерегулярно. (Как указано в описании g-timeout-add () , нарушение может легко произойти.)

В этом примере путь от левого верхнего края окна до левого нижнего и обратно несколько раз. Константа HalfTime в timerEvent () контролирует время, необходимое для перемещения из угла в угол. Константа 3 в вызове g_timeout_add () устанавливает интервал таймера на 0,003 секунды, или около 333 шагов в секунду (MPS). (Возможно, вы захотите попробовать более разумные тарифы, такие как 20, 30, 40 и т. Д. MPS; я использовал число 3, потому что я не смотрел g-timeout-add () перед его использованием и предположил, что задержка составляла сотни секунд, около 33 MPS, а не миллисекунд, около 333 MPS.) Если содержимое вашего окна достаточно сложное, будет меньше MPS. Кроме того, я попробовал некоторые более медленные ставки и получил больше впечатления от хаотичности.

/* $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);
}
...