GTK+/Kalkulator
Ten przykład pokazuje jak użyć biblioteki GTK+ w w miarę funkcjonalnym programie, który realizuje jakieś zadania, niekoniecznie przydatne tylko w edukacji (np. obliczanie delty). Program będzie rozwijany w kolejnych rozdziałach, wykorzystując możliwości biblioteki GTK+.
Kalkulator posiada podstawowe funkcje, dodawanie, odejmowanie, mnożenie, dzielenie. Wspiera intuicyjną obsługę, tzn. posiada ograniczenia zabezpieczające przed użyciem funkcji, których nie można użyć w danym momencie. Przyciski działań (jakie obsługuje kalkulator) w zależności od sytuacji przejmują zadania przycisku sumującego (=). Pozwala to na dodawanie, mnożenie itd. szeregu liczb bez używania przycisku sumy (=) z jednoczesnym wyświetlaniem wyniku.
Założenia te, oraz kilka innych, nieco skomplikowały sam program. Wciąż jednak jest to tylko obsługa (niepełna, rzeczy do zrobienia zostały wymienione w TODO:
) minimalnych funkcji jakie powinien realizować prawdziwy kalkulator. Z czasem program zostanie rozbudowany, na razie jego rozwój został zatrzymany, ponieważ kod obsługi samych mechanizmów zaczął za bardzo przesłaniać samo użycie biblioteki GTK+. Niemniej jednak rozbudowany program uczy więcej.
Oto krótka charakterystyka założeń dotyczących kodu:
- Program składa się z dwóch plików: kalkulator.c oraz kalkulator.h. Można podzielić pierwszy z nich tak, aby funkcje zwrotne GTK+ tzw. callback oraz funkcje niezwiązane z interfejsem graficznym zostały przeniesione do innych plików, np. callback.c oraz corefunction.c. Nie wprowadzono tego, ze względu na łatwiejsze analizowanie kodu z jednego pliku.
- Niektóre funkcje np. obsługi cyfr oraz działań zawierają taki sam kod obsługi zdarzenia, możliwe jest skrócenie kodu poprzez napisanie uogólnionych funkcji (ze względu analizy kodu zostanie to wprowadzone w następnych wersjach programu)
- Program został wyposażony w strukturę dane organizującą niezbędne działanie kalkulatora oraz ich wymianą między wieloma funkcjami zwrotnymi.
- Program został uzbrojony w funkcje debugującą oraz w dyrektywy do ich aktywowania. Stało się to konieczne podczas pewnego poziomu rozwoju programu. Możesz jej użyć do podglądania jakie zmiany zachodzą we wewnętrznej strukturze danych.
- Program został napisany wyłącznie do celów edukacyjnych (oraz dla zabawy), więc wiele rozwiązań w nim zawartych może nie być optymalnymi (np. konwersja napisów na liczby i vice versa). Wszelkie uwagi, błędy oraz propozycje proszę kierować na mój adres e-mail dostępny w (Gk180984).
Kod programu
edytujAnaliza kodu znajduję się w następnym temacie tego rozdziału.
kalkulator.h
struct _Kalkulator {
// pamięć zarządzana przez GTK+
GtkWidget *window;
GtkWidget *table;
GtkWidget *entry;
// pamiec zarządzana przez nas
GString *value1;
GString *value2;
// numer operacji - działania
// 1 +
// 2 -
// 3 *
// 4 /
gshort operation;
// stan kalkulatora
gboolean is_value1;
gboolean is_value2;
gboolean is_result;
// ostatnio wciśnięty przycisk
// 1 1
// 2 2
// ...
// 9 9
// 0 0
// 10 +
// 11 -
// 12 *
// 13 /
// 14 =
// 15 ,
// 16 <-
// 17 C
gint8 prev_button;
};
typedef struct _Kalkulator Kalkulator;
kalkulator.c
/*
* Autor: Grzegorz Kuczyński
* Data: 6 kwietnia 2009
* kompilacja: gcc -Wall -g kalkulator.c -o kalkulator `pkg-config --cflags --libs gtk+-2.0`
*
* TODO
* - sposób wyświetlania wyniku
* - obsługa przecinka (spr błędów)
* - reakcja na backspace - obcinanie końcówki liczby (przycisk <-)
* - sterowanie za pomocą klawiatury numerycznej
* - komunikat dot. dzielenia przez 0
*/
#include <gtk/gtk.h>
#include "kalkulator.h"
#include <stdlib.h>
#include <string.h>
//#define DEBUG
// funkcja debugująca
void info (Kalkulator * pkalkulator, gchar* event)
{
Kalkulator *kalkulator = pkalkulator;
printf ("\n =============\n %s\n - - - - -\nStruktura:\n \
value1: %s \n \
value2: %s \n \
is_value1: %d \n \
is_operatn2: %d \n \
is_result: %d \n \
prev_button: %d \n - - - - -\n",
event,
kalkulator->is_value1 == TRUE? kalkulator->value1->str :"",
kalkulator->is_value2 == TRUE? kalkulator->value2->str :"",
kalkulator->is_value1,
kalkulator->is_value2,
kalkulator->is_result,
kalkulator->prev_button);
}
// funkcja odpowiadająca za właściwe wykonywanie obliczeń na 2 wartościach
void licz(Kalkulator *kalkulator)
{
double d_value1, d_value2, result;
char s_result[50];
d_value1 = strtod( (char*)g_string_free (kalkulator->value1, FALSE),
NULL );
d_value2 = strtod( (char*)g_string_free (kalkulator->value2, FALSE),
NULL );
#ifdef DEBUG
printf ("liczby to %f , %f \n",d_value1,d_value2);
#endif
switch (kalkulator->operation)
{
case 1:
result = d_value1 + d_value2;
break;
case 2:
result = d_value1 - d_value2;
break;
case 3:
result = d_value1 * d_value2;
break;
case 4:
if ( d_value2 >= 1 )
result = d_value1 / d_value2;
else
result = d_value1;
break;
}
sprintf (s_result,"%f",result);
kalkulator->value1 = g_string_new (s_result);
/*
kalkulator->value1 (wynik)
kalkulator->value2 (puste)
*/
}
//==========================================
// obsługa zdarzeń przycisków numerycznych
static void btn_1_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 1\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"1");
kalkulator->prev_button = 1;
}
static void btn_2_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 2\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"2");
kalkulator->prev_button = 2;
}
static void btn_3_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 3\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"3");
kalkulator->prev_button = 3;
}
static void btn_4_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 4\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"4");
kalkulator->prev_button = 4;
}
static void btn_5_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 5\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"5");
kalkulator->prev_button = 5;
}
static void btn_6_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 6\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"6");
kalkulator->prev_button = 6;
}
static void btn_7_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 7\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"7");
kalkulator->prev_button = 7;
}
static void btn_8_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 8\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"8");
kalkulator->prev_button = 8;
}
static void btn_9_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 9\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"9");
kalkulator->prev_button = 9;
}
static void btn_0_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: 0\n");
Kalkulator *kalkulator = pkalkulator;
if ( kalkulator->is_result )
{
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
kalkulator->is_result = FALSE;
}
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),"0");
kalkulator->prev_button = 0;
}
// obsługa zdarzeń przycisków funkcyjnych
static void btn_comma_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: ,\n");
Kalkulator *kalkulator = pkalkulator;
gtk_entry_append_text ( GTK_ENTRY(kalkulator->entry),",");
kalkulator->prev_button = 15;
}
static void btn_back_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: <-\n");
Kalkulator *kalkulator = pkalkulator;
GString *tmp=NULL;
tmp = g_string_new (
gtk_entry_get_text (GTK_ENTRY(kalkulator->entry)));
tmp = g_string_truncate ( tmp, tmp->len - 1 );
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),
g_string_free( tmp, FALSE ) );
kalkulator->prev_button = 16;
}
static void btn_clear_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: C\n");
Kalkulator *kalkulator = pkalkulator;
kalkulator->operation = 0;
if (kalkulator->is_value1 == TRUE)
{
g_string_free (kalkulator->value1,TRUE);
kalkulator->value1 = g_string_new (NULL);
}
if (kalkulator->is_value2 == TRUE)
{
g_string_free (kalkulator->value2,TRUE);
kalkulator->value2 = g_string_new (NULL);
}
kalkulator->is_value1 = FALSE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = FALSE;
gtk_entry_set_text ( GTK_ENTRY(kalkulator->entry),"");
#ifdef DEBUG
info(kalkulator,"clear");
#endif
kalkulator->prev_button = 17;
}
// opsługa zdarzeń przycisków działań
static void btn_add_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: +\n");
Kalkulator *kalkulator = pkalkulator;
gint8 test = 0;
gchar * text_entry = GTK_ENTRY(kalkulator->entry)->text;
// +
kalkulator->operation = 1;
#ifdef DEBUG
info(kalkulator,"w funkcji +");
#endif
// test
if ( kalkulator->is_value1 == FALSE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 )
{
// nalezy ustawić value1
test = 1;
}
if ( kalkulator->is_value1 == TRUE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 &&
kalkulator->prev_button != 10 && // +
kalkulator->prev_button != 11 && // -
kalkulator->prev_button != 12 && // *
kalkulator->prev_button != 13 && // /
kalkulator->prev_button != 14 && // =
kalkulator->prev_button != 15 ) // ,
{
// ustawic value2 i obliczyć wynik
test = 2;
}
switch (test)
{
case 1:
kalkulator->value1 = g_string_new (
gtk_entry_get_text(GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value1 = TRUE;
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
break;
case 2:
kalkulator->value2 = g_string_new (
gtk_entry_get_text(GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value2 = TRUE;
licz (kalkulator);
gtk_entry_set_text (GTK_ENTRY (kalkulator->entry),
(gchar*)kalkulator->value1->str);
kalkulator->is_value1 = TRUE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = TRUE;
break;
}
#ifdef DEBUG
info(kalkulator,"koniec funkcji +");
#endif
kalkulator->prev_button = 10;
}
static void btn_sub_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: -\n");
Kalkulator *kalkulator = pkalkulator;
gint8 test = 0;
gchar * text_entry = GTK_ENTRY(kalkulator->entry)->text;
// -
kalkulator->operation = 2;
#ifdef DEBUG
info(kalkulator,"w funkcji -");
#endif
// test
if ( kalkulator->is_value1 == FALSE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 )
{
// nalezy ustawić value1
test = 1;
}
if ( kalkulator->is_value1 == TRUE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 &&
kalkulator->prev_button != 10 &&
kalkulator->prev_button != 11 &&
kalkulator->prev_button != 12 &&
kalkulator->prev_button != 13 &&
kalkulator->prev_button != 14 &&
kalkulator->prev_button != 15 )
{
// ustawic value2 i obliczyć wynik
test = 2;
}
switch (test)
{
case 1:
kalkulator->value1 = g_string_new (
gtk_entry_get_text (GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value1 = TRUE;
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
break;
case 2:
kalkulator->value2 = g_string_new (
gtk_entry_get_text (GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value2 = TRUE;
licz (kalkulator);
gtk_entry_set_text (GTK_ENTRY (kalkulator->entry),
(gchar*)kalkulator->value1->str);
kalkulator->is_value1 = TRUE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = TRUE;
break;
}
#ifdef DEBUG
info(kalkulator,"koniec funkcji -");
#endif
kalkulator->prev_button = 11;
}
static void btn_multi_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: *\n");
Kalkulator *kalkulator = pkalkulator;
gint8 test = 0;
gchar * text_entry = GTK_ENTRY(kalkulator->entry)->text;
// *
kalkulator->operation = 3;
#ifdef DEBUG
info(kalkulator,"w funkcji *");
#endif
// test
if ( kalkulator->is_value1 == FALSE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 )
{
// nalezy ustawić value1
test = 1;
}
if ( kalkulator->is_value1 == TRUE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 &&
kalkulator->prev_button != 10 &&
kalkulator->prev_button != 11 &&
kalkulator->prev_button != 12 &&
kalkulator->prev_button != 13 &&
kalkulator->prev_button != 14 &&
kalkulator->prev_button != 15 )
{
// ustawic value2 i obliczyć wynik
test = 2;
}
switch (test)
{
case 1:
kalkulator->value1 = g_string_new (
gtk_entry_get_text (GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value1 = TRUE;
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
break;
case 2:
kalkulator->value2 = g_string_new (
gtk_entry_get_text(GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value2 = TRUE;
licz (kalkulator);
gtk_entry_set_text (GTK_ENTRY (kalkulator->entry),
(gchar*)kalkulator->value1->str);
kalkulator->is_value1 = TRUE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = TRUE;
break;
}
#ifdef DEBUG
info(kalkulator,"koniec funkcji *");
#endif
kalkulator->prev_button = 12;
}
static void btn_div_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: /\n");
Kalkulator *kalkulator = pkalkulator;
gint8 test = 0;
gchar * text_entry = GTK_ENTRY(kalkulator->entry)->text;
// /
kalkulator->operation = 4;
#ifdef DEBUG
info(kalkulator,"w funkcji /");
#endif
// test
if ( kalkulator->is_value1 == FALSE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 )
{
// nalezy ustawić value1
test = 1;
}
if ( kalkulator->is_value1 == TRUE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 &&
kalkulator->prev_button != 10 &&
kalkulator->prev_button != 11 &&
kalkulator->prev_button != 12 &&
kalkulator->prev_button != 13 &&
kalkulator->prev_button != 14 &&
kalkulator->prev_button != 15 )
{
// ustawic value2 i obliczyć wynik
test = 2;
}
switch (test)
{
case 1:
kalkulator->value1 = g_string_new (
gtk_entry_get_text(GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value1 = TRUE;
gtk_entry_set_text ( GTK_ENTRY( kalkulator->entry ),"");
break;
case 2:
kalkulator->value2 = g_string_new (
gtk_entry_get_text (GTK_ENTRY(kalkulator->entry)));
kalkulator->is_value2 = TRUE;
licz (kalkulator);
gtk_entry_set_text (GTK_ENTRY (kalkulator->entry),
(gchar*)kalkulator->value1->str);
kalkulator->is_value1 = TRUE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = TRUE;
break;
}
#ifdef DEBUG
info(kalkulator,"koniec funkcji /");
#endif
kalkulator->prev_button = 13;
}
static void btn_result_clicked( GtkWidget *widget,
gpointer pkalkulator )
{
g_print ("clicked: =\n");
Kalkulator *kalkulator = pkalkulator;
// zamiast: ((Kalkulator*)pkalkulator)->operation
gchar * text_entry = GTK_ENTRY(kalkulator->entry)->text;
#ifdef DEBUG
info(kalkulator,"w funkcji =");
#endif
if ( kalkulator->is_value1 == TRUE &&
kalkulator->is_value2 == FALSE &&
strlen (text_entry) > 0 &&
kalkulator->prev_button != 10 &&
kalkulator->prev_button != 11 &&
kalkulator->prev_button != 12 &&
kalkulator->prev_button != 13 &&
kalkulator->prev_button != 14 &&
kalkulator->prev_button != 15 )
{
kalkulator->value2 = g_string_new (
gtk_entry_get_text (GTK_ENTRY(kalkulator->entry))
);
kalkulator->is_value2 = TRUE;
licz (kalkulator);
gtk_entry_set_text (GTK_ENTRY (kalkulator->entry),
(gchar*)kalkulator->value1->str);
kalkulator->is_value1 = TRUE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = TRUE;
}
#ifdef DEBUG
info(kalkulator,"koniec funkcji =");
#endif
kalkulator->prev_button = 14;
}
// obsługa zdarzeń emitowanych podczas zamykania programu
static gboolean delete_event( GtkWidget *widget,
GdkEvent *event,
gpointer data )
{
g_print("delete_event: FALSE\n");
return FALSE;
}
static void destroy( GtkWidget *widget,
gpointer pkalkulator )
{
g_print("destroy: gtk_main_quit | g_free\n");
Kalkulator *kalkulator = pkalkulator;
gtk_main_quit ();
if (kalkulator->is_value1 == TRUE)
{
g_string_free (kalkulator->value1,TRUE);
}
if (kalkulator->is_value2 == TRUE)
{
g_string_free (kalkulator->value2,TRUE);
}
g_free ( kalkulator );
}
int main( int argc, char *argv[] )
{
Kalkulator *kalkulator;
kalkulator = g_malloc ( sizeof( Kalkulator ) );
kalkulator->operation = -1;
kalkulator->is_value1 = FALSE;
kalkulator->is_value2 = FALSE;
kalkulator->is_result = FALSE;
GtkWidget *tmp;
gtk_init (&argc, &argv);
// okno i jego podstawowe właściwości
kalkulator->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
g_signal_connect (G_OBJECT (kalkulator->window), "delete_event",
G_CALLBACK (delete_event), NULL);
g_signal_connect (G_OBJECT (kalkulator->window), "destroy",
G_CALLBACK (destroy), kalkulator);
gtk_container_set_border_width (GTK_CONTAINER (kalkulator->window), 5);
gtk_window_set_title (GTK_WINDOW (kalkulator->window), "kalkulator");
gtk_window_set_resizable ( GTK_WINDOW (kalkulator->window), FALSE );
// tabela
/*
0/0 - 1 - 2 - 3 - 4 - 5 - 6
1 | _ | _ | _ | _ | _ | _ |
2 | _ | _ | _ | _ | _ | _ |
3 | _ | _ | _ | _ | _ | _ |
4 | _ | _ | _ | _ | _ | _ |
*/
kalkulator->table = gtk_table_new (4, 6, TRUE);
gtk_container_add ( GTK_CONTAINER (kalkulator->window),
kalkulator->table);
// entry
kalkulator->entry = gtk_entry_new ( );
gtk_entry_set_alignment ( GTK_ENTRY( kalkulator->entry ), 1);
gtk_entry_set_editable ( GTK_ENTRY( kalkulator->entry ), FALSE);
// 0,6 - szerokość od 0 do 6
// 0,1 - wysokość od 0 do 1
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
kalkulator->entry, 0, 6, 0, 1 );
// przyciski 1
// 0,1 - szerokość od 0 do 1
// 1,2 - wysokość od 1 do 2
tmp = gtk_button_new_with_label ("1");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_1_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 0, 1, 1, 2);
// przyciski 2
tmp = gtk_button_new_with_label ("2");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_2_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 1, 2, 1, 2);
// przyciski 3
tmp = gtk_button_new_with_label ("3");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_3_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 2, 3, 1, 2);
// drugi wiersz
// przyciski 4
tmp = gtk_button_new_with_label ("4");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_4_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 0, 1, 2, 3);
// przyciski 5
tmp = gtk_button_new_with_label ("5");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_5_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 1, 2, 2, 3);
// przyciski 6
tmp = gtk_button_new_with_label ("6");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_6_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 2, 3, 2, 3);
// trzeci wiersz
// przyciski 7
tmp = gtk_button_new_with_label ("7");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_7_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 0, 1, 3, 4);
// przyciski 8
tmp = gtk_button_new_with_label ("8");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_8_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 1, 2, 3, 4);
// przyciski 9
tmp = gtk_button_new_with_label ("9");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_9_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 2, 3, 3, 4);
// przyciski 0
tmp = gtk_button_new_with_label ("0");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_0_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 3, 4, 3, 4);
// przyciski <-
tmp = gtk_button_new_with_label ("<-");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_back_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 3, 4, 2, 3);
// przyciski C
tmp = gtk_button_new_with_label ("C");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_clear_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 3, 4, 1, 2);
// przyciski +
tmp = gtk_button_new_with_label ("+");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_add_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 4, 5, 1, 2);
// przyciski -
tmp = gtk_button_new_with_label ("-");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_sub_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 4, 5, 2, 3);
// przyciski *
tmp = gtk_button_new_with_label ("*");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_multi_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 4, 5, 3, 4);
// przyciski /
tmp = gtk_button_new_with_label ("/");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_div_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 5, 6, 1, 2);
// przyciski =
tmp = gtk_button_new_with_label ("=");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_result_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 5, 6, 3, 4);
// przyciski ,
tmp = gtk_button_new_with_label (",");
g_signal_connect (G_OBJECT (tmp), "clicked",
G_CALLBACK (btn_comma_clicked), kalkulator);
gtk_table_attach_defaults ( GTK_TABLE (kalkulator->table),
tmp, 5, 6, 2, 3);
gtk_widget_show_all (kalkulator->window);
#ifdef DEBUG
info(kalkulator,"przed gatk_main");
#endif
gtk_main ();
return 0;
}