Σπάστε πλάκα με την Gtk+3 καθώς μαθαίνουμε!!!

...το μέρος για να ξεκινήσετε!

Συντονιστής: adem1

Κανόνες Δ. Συζήτησης
Παρακαλώ να επιλέξετε, με προσοχή, την άδεια που θέλετε να έχουν οι οδηγοί που συγγράφετε.
Πληροφορίες για τις άδειες μπορείτε να βρείτε εδώ.
Άμα επιθυμείτε κάποια άλλη άδεια επικοινωνήστε με κάποιο Διαχειριστή είτε Συντονιστή.

Σημαντικό είναι να χρησιμοποιήσετε την υπηρεσία http://imagebin.ubuntu-gr.org για τις εικόνες.

Σπάστε πλάκα με την Gtk+3 καθώς μαθαίνουμε!!!

Δημοσίευσηαπό pc_magas » 07 Νοέμ 2012, 17:30

Καθώς δοκιμάζω να κάνω πράγματα με την gtk σκέφτηκα έναν ωραίο προγραμματάκι για να σπάτε πλάκα στους φίλους σας.

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

Αρχικά Συστατικά:
  • Τερματικό για compile
  • make
  • Ο φίλος σας που τρέχει και αυτός linux και θέλεται να σπάσετε πλάκα ;)
[*]Να έχετε εγκατεστημένη την gtk3+ (delelopment packages)

Ο κώδικας είναι ο εξής:

Κώδικας: Επιλογή όλων

#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.
  1. Η πρώτη παράμετρος είναι σε ποιο αντικείμενο θα γίνεται αυτή η ενέργεια.
  2. Η δεύτερη ορρίζουμε ποιά είναι η ενέργεια.
  3. Η τρίτη παράμετρος (μέσα σε G_CALLBACK) είναι η συνάρτηση που θα καλείτε για την ενέργεια αυτήν. Και πρέπει να ορίζεται ως εξής:
    Κώδικας: Επιλογή όλων
    static void <όνομα>(GtkWidget *widget, gpointer data)
  4. Βλέπουμε στο παραπάνω format συνάρτησης ότι με την δεύτερη παράμετρο\ παίρνουμε τα δεδομένα που χρειαζόμαστε. Άρα στην g_signal_connect ως τελευταία παράμετρο βάζουμε έναν pointer που οδηγεί στα δεδομένα αυτά.
[/list]
Ακόμη προσθέτουμε ένα 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 έτσι να αλλάζει το όνομα του εκτελέσιμου. (Άσκηση για το σπίτι ;) )

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

Όπως και να έχει καλό είναι να το κάνετε καλοπροαίρετα και όχι μόνο για πλάκα αλλά και αφορμή για να ψάξεται στο πως γίνονται τα gtk aps και το πως βολικό είναι το make. Και καλές φάρσες!!! :lol: :lol: :lol:
Τελευταία επεξεργασία από pc_magas και 26 Απρ 2013, 19:46, έχει επεξεργασθεί 1 φορά/ες συνολικά
My blog|Κυπριακή Κοινότητα Ελευθέρου Λογισμικού Λογισμικού ανοικτού Κώδικα
Γνώσεις Linux:Ποτέ αρκετές|Προγραμματισμός: Php, javascript, nodejs, python, bash |Aγγλικά:Καλά
Οι υπολογιστές μου:
Spoiler: show
Ubuntu 16.04 64 bit σεIntel(R) Pentium(R) CPU G4400 @ 3.30GHz, 16Gib Ram, 500Gib Hard Disk, και κάρτα γραφικών Nvidia Geforce GT610
Lubuntu 14.04 σε Dell Inspiron mini 10(1010) intel Atom Z500 1Gb ram και gma500 (εδώθη σε άλλον)
Kubuntu 16.04 Lenovo G70 Intel i5 Nvidia Grapgics Card, Intel Graphics card (έχει 2) με Nouveau, 16Gb RAM, 126GB SSD Σκληρό Δίσκο
Άβαταρ μέλους
pc_magas
powerTUX
powerTUX
 
Δημοσιεύσεις: 2599
Εγγραφή: 12 Απρ 2009, 18:55
Τοποθεσία: Αχαρναί Αττικής
Launchpad: pc_magas
IRC: pc_magas
Εκτύπωση

Re: Σπάστε πλάκα με την Gtk+3 καθώς μαθαίνουμε!!!

Δημοσίευσηαπό jemadux » 26 Απρ 2013, 11:20

δεν το διατυπωνεις σωστα... πρεπει και αλλος να εχει gtk3 εγκατεστημενη για να δουλεψει
1 Γνώσεις Linux: ✅✅✅✔️✔️ ┃ Προγραμματισμού: ✔️✔️✔️✔️✔️ ┃ Αγγλικών: ✅✅✅✔️✔️
2 Debian Stable (en_US.UTF-8)
3 AMD Ryzen 5 2500U Radeon Vega Mobile Gfx ‖ RAM 16MiB ‖ Dell Inspiron 3585
4 Radeon Vega Mobile Gfx
5 Qualcomm Atheros QCA9377 802.11ac Wireless Network Adapter
Άβαταρ μέλους
jemadux
daemonTUX
daemonTUX
 
Δημοσιεύσεις: 841
Εγγραφή: 27 Σεπ 2009, 19:39
Τοποθεσία: /dev/null
IRC: jemadux
Εκτύπωση

Re: Σπάστε πλάκα με την Gtk+3 καθώς μαθαίνουμε!!!

Δημοσίευσηαπό pc_magas » 26 Απρ 2013, 19:44

jemadux έγραψε:δεν το διατυπωνεις σωστα... πρεπει και αλλος να εχει gtk3 εγκατεστημενη για να δουλεψει

Ευχαριστώ για την σημείωση...
My blog|Κυπριακή Κοινότητα Ελευθέρου Λογισμικού Λογισμικού ανοικτού Κώδικα
Γνώσεις Linux:Ποτέ αρκετές|Προγραμματισμός: Php, javascript, nodejs, python, bash |Aγγλικά:Καλά
Οι υπολογιστές μου:
Spoiler: show
Ubuntu 16.04 64 bit σεIntel(R) Pentium(R) CPU G4400 @ 3.30GHz, 16Gib Ram, 500Gib Hard Disk, και κάρτα γραφικών Nvidia Geforce GT610
Lubuntu 14.04 σε Dell Inspiron mini 10(1010) intel Atom Z500 1Gb ram και gma500 (εδώθη σε άλλον)
Kubuntu 16.04 Lenovo G70 Intel i5 Nvidia Grapgics Card, Intel Graphics card (έχει 2) με Nouveau, 16Gb RAM, 126GB SSD Σκληρό Δίσκο
Άβαταρ μέλους
pc_magas
powerTUX
powerTUX
 
Δημοσιεύσεις: 2599
Εγγραφή: 12 Απρ 2009, 18:55
Τοποθεσία: Αχαρναί Αττικής
Launchpad: pc_magas
IRC: pc_magas
Εκτύπωση


Επιστροφή στο Οδηγοί - How to - Tutorials