Η ιδέα είναι απλή:
Είναι ένα παράθυρο με ένα κουμπί που λέει close αλλά στην ουσία δεν το κλείνει αλλά πετάει ένα νέο παράθυρο με κουμπί που λέει close όπου κάνει τι ίδιο πράγμα. Δε άμα το κλείσεις με το κουμπί χ πάνω δεξιά αυτό ξαναεμφανίζεται!!!


Αρχικά Συστατικά:
- Τερματικό για compile
- make
- Ο φίλος σας που τρέχει και αυτός linux και θέλεται να σπάσετε πλάκα
Ο κώδικας είναι ο εξής:
- Κώδικας: Επιλογή όλων
#include<gtk/gtk.h>
/*This function prints something*/
static void print_hello(GtkWidget *widget, gpointer data)
{
g_print("Hello\n");//prints a message
makeWindow("Hello");//creates a window
}
static gboolean on_delete_event (GtkWidget *widget, GdkEvent *event,gpointer data)
{
/* If you return FALSE in the "delete_event" signal handler,
* GTK will emit the "destroy" signal. Returning TRUE means
* you don't want the window to be destroyed.
*
* This is useful for popping up 'are you sure you want to quit?'
* type dialogs.
*/
g_print ("delete event occurred\n");
return FALSE;
}
/*Thins function makes a window*/
void makeWindow(const unsigned char title[])
{
/*Components*/
GtkWidget *window;
GtkWidget *button;
/*Making the window*/
window=gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), title);
gtk_container_set_border_width (GTK_CONTAINER (window), 20);
/*Making the Button*/
button = gtk_button_new_with_label ("Close");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
gtk_container_add (GTK_CONTAINER (window), button);
/*Connecting Signals*/
g_signal_connect (window, "destroy", G_CALLBACK (print_hello), NULL);//reopen the window
g_signal_connect (window, "delete-event", G_CALLBACK (on_delete_event), NULL);
/* The final step is to display this newly created widget... */
gtk_widget_show (button);
/* ... and the window */
gtk_widget_show (window);
}
int main(int argc, char *argv[])
{
gtk_init(&argc,&argv);//Initialising Gtk
makeWindow("Hello");//This function does the "dirty job"
gtk_main ();//Required to run a gtk app
return 0;
}
Αναλυτικότερα:
Η print_hello καλείτε όταν πατιέται το κουμπί Close ή κλείνεται το παράθυρο δηλαδή κάνει όλη την "σκοτεινή και υποχθόνια" δουλειά.
Κάθε εξάρτημα του παραθύρου σας και κάθε παράθυρο υλοποιείται με την struct GtkWidget. Για κάθε ένα component του γραφικού περιβάλοντος Gtk είναι ένας pointer τύπου GtkWidget.
Το τι θα εκτελέιτε σε κάθε ενέργεια σε ένα παράθυρο gtk μπορείτε να το ορίσετε με το macro:
- Κώδικας: Επιλογή όλων
g_signal_connect (<component>,"<όνομα_ενέργειας>" G_CALLBACK (<όνομα_function>),<Pointer σε δεδομένα>)
Δηλαδή:
Ο κώδικας που εμφανίζει το gui μας βρίσκεται μεταξύ των εξής κλήσεων συνάρτησης:
έγραψε:
gtk_init(&argc,&argv);
/*Κώδικας εμφάνισης Gui*/
gtk_main ();
Παρόμοιες κλήσεις παρόμοιων συναρτήσεων και σε άλλες βιβλιοθήκες που μπορεί κάνουν και διαφορετικά πράγματα από το να εμφανίζουν gui πχ.MPI.
- Η πρώτη παράμετρος είναι σε ποιο αντικείμενο θα γίνεται αυτή η ενέργεια.
- Η δεύτερη ορρίζουμε ποιά είναι η ενέργεια.
- Η τρίτη παράμετρος (μέσα σε G_CALLBACK) είναι η συνάρτηση που θα καλείτε για την ενέργεια αυτήν. Και πρέπει να ορίζεται ως εξής:
- Κώδικας: Επιλογή όλων
static void <όνομα>(GtkWidget *widget, gpointer data)
- Βλέπουμε στο παραπάνω format συνάρτησης ότι με την δεύτερη παράμετρο\ παίρνουμε τα δεδομένα που χρειαζόμαστε. Άρα στην g_signal_connect ως τελευταία παράμετρο βάζουμε έναν pointer που οδηγεί στα δεδομένα αυτά.
Ακόμη προσθέτουμε ένα component έσα σε ένα άλλο component του gui με την:
έγραψε:gtk_container_add (GTK_CONTAINER (<component_που_θα_περιέχει_το_component>), <component>);
Δηλαδή λέμε στην πρώτη παράμετρο που είναι το component (παράθυρο κλπ κλπ.) που θα φιλοξενεί το component της δεύτερης παραμέτρου που είναι το κουμπί
Τώρα η παραπάνω κώδικας μπορεί να γίνει compile έτσι:
- Κώδικας: Επιλογή όλων
gcc `pkg-config --cflags gtk+-3.0` -o <όνομα_εκτελέσιμου> <όνομα_αρχείου_κώδικα>.c `pkg-config --libs gtk+-3.0`
Αλλά στο μέλλον μπορεί να χρειαστεί να κάνετε τροποπίηση στων παραπάνω κώδικα αλλά που να θυμάστε τι flags χρειάζονται για να γίνεται compile. Άρα με ένα makefile αρχείο θα είστε καλυμένοι:
- Κώδικας: Επιλογή όλων
FLAGS=`pkg-config --cflags gtk+-3.0`
LIBS=`pkg-config --libs gtk+-3.0`
CC= gcc
CFILE=mygtk
main:
${CC} ${FLAGS} -o ${CFILE} ${CFILE}.c ${LIBS}
Η φιλοσοφία πίσω από το makefile είναι στην ουσία στο πάνω μέρος ορίζοντας "μεταβλητές" και στο κάτω ορίζουμε ένα compilation tree. Κάθε εγγραφή του makefile είναι ένα target και μπορείς να πείς ότι συντάσεται έτσι:
- Κώδικας: Επιλογή όλων
<όνομα_target>: <προαπαιτούμενος_στόχος_ή_αρχείο1>,<προαπαιτούμενος_στόχος_ή_αρχείο2>,....
<εντόλή για compile>
Δηλαδή έχει ένα στόχο που χρειάζεται κάποια προαπαιτούμενα αρχεία κώδικα πχ λόγο ότι είναι βιβλιοθήκη ή να επιτευχθεί κάποιος άλλος στόχος πχ. να μεταγλωττιστεί πρώτα μια βιβλιοθήκη.
Ακόμη στην εντολή αντί να γράφουμε τα ίδια κομμάτια που ενδεχωμένως να χρειάζεται και σε επόμενους στόχους (πχ. το όνομα του compiler η κάποια flags βπου χρειάζεται μια βιβλιοθήκη) μπορούμε να τα βάλουμε σε μια μεταβλητή στην αρχή του κειμένου. και στο σημέιο της εντολής να βάλουμε:
- Κώδικας: Επιλογή όλων
${<όνομα_μεταβλητής>}
εκεί που χρειάζεται. Πχ.
- Κώδικας: Επιλογή όλων
${CC} ${FLAGS} -o ${CFILE} ${CFILE}.c ${LIBS}
θα σχηματιστεί η εντολή:
- Κώδικας: Επιλογή όλων
gcc `pkg-config --cflags gtk+-3.0` -o mygtk mygtk.c `pkg-config --libs gtk+-3.0`
Γιατί στο ${CC} έχω ορίσει την τιμή gcc στα ${FLAGS} την τιμή `pkg-config --cflags gtk+-3.0` κλπ κλπ.
Τώρα εφόσον κάνατε σωστά copy-paste τον κώδικα στο αρχείο με mygtk.c και Κάνατε copy paste το Makefile (είναι ξεχωρτιστό αρχείο με το όνομα Makefile). Και αποθηκεύσατε τα 2 αρχεία στον ίδιο κατάλογο. (Αν δεν είναι στον ίδιο κατάλογο φροντίστε να είναι) Ανοίξτε τερματικό και δώστε. Για να γίνει compile.
- Κώδικας: Επιλογή όλων
cd <η_διαδρομή_του_κατάλογου> && make
Και αφήστε το ανοικτό.
Το εκτελέσιμο θα είναι το mygtk για να το τρέξετε απλά δώστε:
- Κώδικας: Επιλογή όλων
./mygtk
Και κλείνει με Ctrl+C ή κλείνοντας το τερματικό
Για αλλαγή μπορείτε να το μεταονομάσεται όπως θέλεται. Η να τροποποιήσετε το makefile έτσι να αλλάζει το όνομα του εκτελέσιμου. (Άσκηση για το σπίτι

Και τώρα εφόσον είδαμε αρκεί να το "πασάρουμε" στον φίλο μας. Υπάρχουν πολλοί τρόποι:
- Να του το δώσετε με ένα στικάκι να το εκτελέσει στον υπολογιστή του και είστε εκεί με μια κάμερα όταν το εκτελεί για να γελάσετε με την ψυχή σας.
- Να του το πασάρετε μέσω skype,IM. Και μετά να δείτε πως πάει από 0-100 μπινελίκια/sec.
Όπως και να έχει καλό είναι να το κάνετε καλοπροαίρετα και όχι μόνο για πλάκα αλλά και αφορμή για να ψάξεται στο πως γίνονται τα gtk aps και το πως βολικό είναι το make. Και καλές φάρσες!!!


