GTK coding

Модератор: Fastman

Правила форума
Убедительная просьба юзать теги [code] при оформлении листингов.
Сообщения не оформленные должным образом имеют все шансы быть незамеченными.
Pal
мл. сержант
Сообщения: 97
Зарегистрирован: 2008-07-04 14:40:14

GTK coding

Непрочитанное сообщение Pal » 2009-06-28 18:39:47

Всем привет!
Завтра экзамен в универе, необходим принести задания:

Код: Выделить всё

1.Создать модель движения графического объекта в двумерном пространстве с использованием объекта CANVAS.
2.Разработать программу управления графическим объектом на основе обработки событий нажатия клавиш.
3.Программа взаимодействия нескольких визуальных  форм с использованием listbox, edit, button.
4.Программа иллюстрирующая движение материальной точки вокруг начал координат, при этом сама материальная точка является центром масс равностороннего, вращающегося треугольника (с использованием timer – 2).
5.Визуальное отображение закрашенного круга, разбитого по секторам.  Цвета переключаются по таймеру.
Всё это, как я понимаю необходимо было делать на delphi. Но винды у меня нету и delphi соответственно тоже. Решил писать на GTK+, дабы там есть похожая библиотека GooCanvas.
В общем первые два задания сделал:

Код: Выделить всё

/* 
#include <goocanvas.h>

static gboolean on_delete_event (GtkWidget *window,
				GdkEvent *event,
				gpointer unused_data);

static double drag_x, drag_y;
static gboolean dragging = FALSE;
static void create_canvas_items(GooCanvas *canvas);

int
main (int argc, char *argv[])
{
	GtkWidget *window, *scrolled_win, *canvas;

	/* Initialize GTK+. */
	gtk_set_locale ();
	gtk_init (&argc, &argv);

	/* Create the window and widgets. */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window), "First task");
	gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
	gtk_widget_show (window);
	g_signal_connect (window, "delete_event", (GtkSignalFunc) on_delete_event, 
		      NULL);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
					 GTK_SHADOW_IN);
	gtk_widget_show (scrolled_win);
	gtk_container_add (GTK_CONTAINER (window), scrolled_win);

	canvas = goo_canvas_new ();
	gtk_widget_set_size_request (canvas, 50, -1);
	goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 604, 454);

	create_canvas_items(GOO_CANVAS (canvas));

	gtk_widget_show (canvas);
	gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);

	/* Pass control to the GTK+ main event loop. */
	gtk_main ();

	return 0;
}



/* This is our handler for the "delete-event" signal of the window, which
 * is emitted when the 'x' close button is clicked. We just exit here. */
static gboolean
on_delete_event (GtkWidget *window,
	   GdkEvent  *event,
	   gpointer   unused_data)
{
	exit (0);
}

static gboolean
on_button_release (GooCanvasItem *item,
           GooCanvasItem *target,
           GdkEventButton *event,
           gpointer data)
{
  GooCanvas *canvas;

  canvas = goo_canvas_item_get_canvas (item);
  goo_canvas_pointer_ungrab (canvas, item, event->time);
  dragging = FALSE;

  return TRUE;
}

static gboolean
on_motion_notify (GooCanvasItem *item,
          GooCanvasItem *target,
          GdkEventMotion *event,
          gpointer data)
{
  if (dragging && (event->state & GDK_BUTTON1_MASK))
    {
      double new_x = event->x;
      double new_y = event->y;

      goo_canvas_item_translate (item, new_x - drag_x, new_y - drag_y);
    }

  return TRUE;
}

static gboolean
on_button_press (GooCanvasItem *item,
         GooCanvasItem *target,
         GdkEventButton *event,
         gpointer data)
{
  GooCanvas *canvas;
  GdkCursor *fleur;

  canvas = goo_canvas_item_get_canvas (item);

  switch (event->button)
    {
    case 1:
      if (event->state & GDK_SHIFT_MASK)
    {
      goo_canvas_item_remove (item);
    }
      else
    {
      drag_x = event->x;
      drag_y = event->y;

      fleur = gdk_cursor_new (GDK_FLEUR);
      goo_canvas_pointer_grab (canvas, item,
                   GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK,
                   fleur,
                   event->time);
      gdk_cursor_unref (fleur);
      dragging = TRUE;
    }
      break;

    case 2:
      goo_canvas_item_lower (item, NULL);
      break;

    case 3:
      goo_canvas_item_raise (item, NULL);
      break;

    default:
      break;
    }

  return TRUE;
}

static void
setup_item(GooCanvasItem *item)
{
  g_signal_connect (item, "motion_notify_event",
            G_CALLBACK (on_motion_notify), NULL);
  g_signal_connect (item, "button_press_event",
            G_CALLBACK (on_button_press), NULL);
  g_signal_connect (item, "button_release_event",
            G_CALLBACK (on_button_release), NULL);
}

static void
create_canvas_items(GooCanvas *canvas)
{
	GooCanvasItem *root, *text_item, *ellipse_item, *ellipse1, *ellipse2, *rect1;

	root = goo_canvas_get_root_item (GOO_CANVAS (canvas));

	/* Add a few simple items. */
	ellipse1 = goo_canvas_ellipse_new (root, 0, 0, 25, 15,
				     "fill-color", "blue",
				     NULL);

	ellipse2 = goo_canvas_ellipse_new (root, 0, 0, 25, 15,
				     "fill-color", "red",
				     NULL);

	rect1 = goo_canvas_rect_new (root, -10, -10, 20, 20,
			       "fill-color", "blue",
			       NULL);

	setup_item(goo_canvas_rect_new (root, 90.0, 40.0, 90.0, 60.0,
				  "stroke-color", "black",
				  "line-width", 4.0,
				  "fill_color_rgba", 0x3cb37180,
				  NULL));


	goo_canvas_item_set_simple_transform (ellipse1, 100, 100, 1, 0);
	goo_canvas_item_animate (ellipse1, 500, 100, 2, 720, TRUE, 2000, 40,
			   GOO_CANVAS_ANIMATE_BOUNCE);

	goo_canvas_item_set_simple_transform (ellipse2, 100, 400, 1, 0);
	goo_canvas_item_animate (ellipse2, 400, 0, 2, 720, FALSE, 2000, 40,
			   GOO_CANVAS_ANIMATE_BOUNCE);

	goo_canvas_item_set_simple_transform (rect1, 100, 200, 1, 0);
	goo_canvas_item_animate (rect1, 100, 200, 1, 350, TRUE, 40 * 36, 40,
			   GOO_CANVAS_ANIMATE_RESTART);
} 
Помогите люди добрые:) Впервые в жизни вижу GTK, в третьем задании надо заюзать listbox, никак не могу его найти в GTK, может кто знает чем заменить или как делать?
В 5ом задании не могу представить себе сам алгоритм. Допустим создам 4 item'а образующих круг, но по какому событию мне их убирать или закрашивать, если необходимо это делать по таймеру?

Спасибо

Хостинговая компания Host-Food.ru
Хостинг HostFood.ru
 

Услуги хостинговой компании Host-Food.ru

Хостинг HostFood.ru

Тарифы на хостинг в России, от 12 рублей: https://www.host-food.ru/tariffs/hosting/
Тарифы на виртуальные сервера (VPS/VDS/KVM) в РФ, от 189 руб.: https://www.host-food.ru/tariffs/virtualny-server-vps/
Выделенные сервера, Россия, Москва, от 2000 рублей (HP Proliant G5, Intel Xeon E5430 (2.66GHz, Quad-Core, 12Mb), 8Gb RAM, 2x300Gb SAS HDD, P400i, 512Mb, BBU):
https://www.host-food.ru/tariffs/vydelennyi-server-ds/
Недорогие домены в популярных зонах: https://www.host-food.ru/domains/

Аватара пользователя
Fastman
ст. лейтенант
Сообщения: 1236
Зарегистрирован: 2006-07-07 10:20:38
Откуда: Минск. РБ

Re: GTK coding

Непрочитанное сообщение Fastman » 2009-06-28 23:54:21

Взял бы нормальный QT 4.5, было бы проще намного.Вменяемая документация на все случаи жизни с примерами. Да и тут быстрее бы подсказали.
Но все фигня. Принесешь в универ - а там винда и нету unix-а и(или) GTK :)
Что за привычка приключения себе на пятую точку искать :)
Главное в жизни здоровье и любовь, остальное я все куплю.

zg
полковник
Сообщения: 5845
Зарегистрирован: 2007-12-07 13:51:33
Откуда: Верх-Нейвинск

Re: GTK coding

Непрочитанное сообщение zg » 2009-06-29 5:46:32

Fastman писал(а):Принесешь в универ - а там винда и нету unix-а и(или) GTK
дак поди не абы как, на дискете понесёт :roll:
Pal писал(а):но по какому событию мне их убирать или закрашивать, если необходимо это делать по таймеру?
в венде объект таймер был с событием, тут скорее всего аналогично. А вообще да, на QT было бы сподручней, как никак он и под венду есть.
Pal писал(а):Всё это, как я понимаю необходимо было делать на delphi.
заочник? :smile:

Pal
мл. сержант
Сообщения: 97
Зарегистрирован: 2008-07-04 14:40:14

Re: GTK coding

Непрочитанное сообщение Pal » 2009-06-29 14:23:22

Всё сдал, всем спасибо).
Да, я заочник.

Pal
мл. сержант
Сообщения: 97
Зарегистрирован: 2008-07-04 14:40:14

Re: GTK coding

Непрочитанное сообщение Pal » 2009-06-29 16:23:21

Может кому для универа понадобится или вообще, как пример кода:

Чтобы скомпилить надо поставить goocanvas библиотеку, в Linux пакетом есть и в rpm и в deb, вроде как в FreeBSD в портах тоже валяется.
И собственно компилим так:
gcc -g `pkg-config --cflags goocanvas --libs gtk+-2.0` file_with_code.c

Зелёный вращающийся прямоугольник кликабелен;)

Код: Выделить всё

#include <goocanvas.h>

static gboolean on_delete_event (GtkWidget *window,
				GdkEvent *event,
				gpointer unused_data);

static double drag_x, drag_y;
static gboolean dragging = FALSE;
static void create_canvas_items(GooCanvas *canvas);
static gboolean time_handler(GtkWidget *widget);
int i = 0;

GooCanvasItem *root, *text_item, *ellipse_item, *ellipse1, *ellipse2, *rect1, *rect2;

int
main (int argc, char *argv[])
{
	GtkWidget *window, *scrolled_win, *canvas;

	/* Initialize GTK+. */
	gtk_set_locale ();
	gtk_init (&argc, &argv);

	/* Create the window and widgets. */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window), "First task");
	gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
	gtk_widget_show (window);
	g_signal_connect (window, "delete_event", (GtkSignalFunc) on_delete_event, //Обработчик сигнала, виджет window создаёт сигнал on_delete_event, вызывается функция on_delete_event.
		      NULL);

	scrolled_win = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
					 GTK_SHADOW_IN);
	gtk_widget_show (scrolled_win);
	gtk_container_add (GTK_CONTAINER (window), scrolled_win);

	canvas = goo_canvas_new ();
	gtk_widget_set_size_request (canvas, 50, -1);
	goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 604, 454);

	create_canvas_items(GOO_CANVAS (canvas));
	g_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) window);

	gtk_widget_show (canvas);
	gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);

	/* Pass control to the GTK+ main event loop. */
	gtk_main ();

	return 0;
}



/* This is our handler for the "delete-event" signal of the window, which
 * is emitted when the 'x' close button is clicked. We just exit here. */
static gboolean
on_delete_event (GtkWidget *window,
	   GdkEvent  *event,
	   gpointer   unused_data)
{
	printf("Нажата кнопа 'x'. Выходим из программы\n");
	exit (0);
}

static gboolean
on_button_release (GooCanvasItem *item,
           GooCanvasItem *target,
           GdkEventButton *event,
           gpointer data)
{
  GooCanvas *canvas;

  canvas = goo_canvas_item_get_canvas (item);
  goo_canvas_pointer_ungrab (canvas, item, event->time);
  dragging = FALSE;

  return TRUE;
}

static gboolean
on_motion_notify (GooCanvasItem *item,
          GooCanvasItem *target,
          GdkEventMotion *event,
          gpointer data)
{
  if (dragging && (event->state & GDK_BUTTON1_MASK))
    {
      double new_x = event->x;
      double new_y = event->y;

      goo_canvas_item_translate (item, new_x - drag_x, new_y - drag_y);
    }

  return TRUE;
}

static gboolean
on_button_press (GooCanvasItem *item,
         GooCanvasItem *target,
         GdkEventButton *event,
         gpointer data)
{
	goo_canvas_item_stop_animation(item);
  GooCanvas *canvas;
  GdkCursor *fleur;

  canvas = goo_canvas_item_get_canvas (item);

  switch (event->button)
    {
    case 1:
      if (event->state & GDK_SHIFT_MASK)
    {
      goo_canvas_item_remove (item);
    }
      else
    {
      drag_x = event->x;
      drag_y = event->y;

      fleur = gdk_cursor_new (GDK_FLEUR);
      goo_canvas_pointer_grab (canvas, item,
                   GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK,
                   fleur,
                   event->time);
      gdk_cursor_unref (fleur);
      dragging = TRUE;
    }
      break;

    case 2:
      goo_canvas_item_lower (item, NULL);
      break;

    case 3:
      goo_canvas_item_raise (item, NULL);
      break;

    default:
      break;
    }

  return TRUE;
}

static void
setup_item(GooCanvasItem *item)
{
  g_signal_connect (item, "motion_notify_event",
            G_CALLBACK (on_motion_notify), NULL);
  g_signal_connect (item, "button_press_event",
            G_CALLBACK (on_button_press), NULL);
  g_signal_connect (item, "button_release_event",
            G_CALLBACK (on_button_release), NULL);
}

static void
create_canvas_items(GooCanvas *canvas)
{
	root = goo_canvas_get_root_item (GOO_CANVAS (canvas));

	/* Add a few simple items. */
	ellipse1 = goo_canvas_ellipse_new (root, 0, 0, 25, 15,
				     "fill-color", "blue",
				     NULL);

	ellipse2 = goo_canvas_ellipse_new (root, 0, 0, 25, 15,
				     "fill-color", "red",
				     NULL);

	rect1 = goo_canvas_rect_new (root, -10, -10, 20, 20,
			       "fill-color", "blue",
			       NULL);

	rect2 = goo_canvas_rect_new (root, 90.0, 40.0, 90.0, 60.0,
					  "stroke-color", "black",
					  "line-width", 4.0,
					  "fill_color_rgba", 0x3cb37180,
					  NULL);

	setup_item(rect2);


	goo_canvas_item_set_simple_transform (ellipse1, 100, 100, 1, 0);
	goo_canvas_item_animate (ellipse1, 500, 100, 2, 720, TRUE, 2000, 40,
			   GOO_CANVAS_ANIMATE_BOUNCE);

	goo_canvas_item_set_simple_transform (ellipse2, 100, 400, 1, 0);
	goo_canvas_item_animate (ellipse2, 400, 0, 2, 720, FALSE, 2000, 40,
			   GOO_CANVAS_ANIMATE_BOUNCE);

	goo_canvas_item_set_simple_transform (rect1, 100, 200, 1, 0);
	goo_canvas_item_animate (rect1, 100, 200, 1, 350, TRUE, 40 * 36, 40,
			   GOO_CANVAS_ANIMATE_RESTART);

	goo_canvas_item_set_simple_transform (rect2, 100, 200, 1, 0);
	goo_canvas_item_animate (rect2, 100, 200, 1, 350, TRUE, 2000, 40,
			   GOO_CANVAS_ANIMATE_RESTART);
} 

static gboolean
time_handler(GtkWidget *widget)
{
	if (i == 1)
	{
	g_object_set((gpointer) ellipse1,"fill-color","blue",NULL);
	g_object_set((gpointer) ellipse2,"fill-color","blue",NULL);
	i = 2;
	}
	else if (i == 0)
	{
	g_object_set((gpointer) ellipse1,"fill-color","red",NULL);
	g_object_set((gpointer) ellipse2,"fill-color","red",NULL);
	i = 1;
	}
	else if (i == 2)
	{
	g_object_set((gpointer) ellipse1,"fill-color","yellow",NULL);
	g_object_set((gpointer) ellipse2,"fill-color","yellow",NULL);
	i = 0;
	}
}

Аватара пользователя
Fastman
ст. лейтенант
Сообщения: 1236
Зарегистрирован: 2006-07-07 10:20:38
Откуда: Минск. РБ

Re: GTK coding

Непрочитанное сообщение Fastman » 2009-06-29 16:26:34

Всегда поражало кто мог такое придумать :)))

Код: Выделить всё

goo_canvas_item_set_simple_transform 
Фтопку.
Главное в жизни здоровье и любовь, остальное я все куплю.