Open source repositories at: github and bitbucket. Current project: erp4all

Sunday, May 22, 2011

Γνωριμία με το Glade (α' μέρος)

Το Glade είναι μια εφαρμογή για την δημιουργία του UI ενός προγράμματος σε GTK. Η μεθοδολογία που ακολουθείται είναι ο σχεδιασμός με την προσθήκη διάφορων αντικειμένων (παράθυρα, button, menu κλπ), η τακτοποίηση αυτών στο παράθυρο, η μεταβολή των ιδιοτήτων τους (χρώμα, μέγεθος, συμπεριφορά κλπ) και η σύνδεση των σημάτων που στέλνουν, σε απάντηση ενέργειας του χρήστη, με ρουτίνες του προγράμματος (πχ όταν πατήσει ο χρήστης το X κλεισίματος στο παράθυρο τι θα κάνει το πρόγραμμα).


Φτιάχνει ένα αρχείο XML όπου περιγράφει όλα τα παραπάνω και είναι δουλειά του προγράμματος να το διαβάσει, να δημιουργήσει τα αντικείμενα και να τα εμφανίσει.
Υπάρχουν βιβλιοθήκες που κάνουν ακριβώς αυτό για όλες της σημαντικές γλώσσες C++, perl, python, ruby. Εδώ θα ασχοληθούμε με την python, μια πολύ διαδεδομένη γλώσσα με βιβλιοθήκες και προγράμματα για ότι μπορεί κανείς να φανταστεί. Θα γράψουμε ένα πρόγραμμα για την εύκολη δημιουργία του αρχείου XML εναλλαγής φόντων που σχολιάσαμε σε προηγούμενο άρθρο.

Όταν ξεκινάει το Glade παρουσιάζεται το εξής παράθυρο όπου ζητάει ορισμένα στοιχεία για να ξεκινήσει την δημιουργία του έργου. Στο “Μορφή έργου” διαλέγουμε το GtkBuilder γιατί το libglade είναι προς κατάργηση, και επιλέγουμε την μεγαλύτερη έκδοση toolkit που είναι διαθέσιμη. Το συγκεκριμένο Glade είναι το 3.6.7 από την διανομή Ubuntu Lucid και έχει την 2.16 σαν μεγαλύτερη. Στην Natty διανομή υπάρχει το Glade 3.8 και toolkit 2.24. Αφήνουμε τα υπόλοιπα προεπιλεγμένα χαρακτηριστικά και πατάμε “Κλείσιμο”.

  1. Για αρχή επιλέγουμε “Παράθυρο” το οποίο είναι το βασικό αντικείμενο το οποίο περιέχει αυτά που θέλουμε να εμφανίσουμε.
  2. Αλλάζουμε το όνομα του σε “backgroundxml” για να υπάρχει μια ενιαία ονοματολογία.
  3. Ο τίτλος του παραθύρου: BackgroundXML είναι αυτό που θα εμφανίζεται πάνω στην μπάρα όταν τρέχει το πρόγραμμα.
  4. Βάζουμε ένα γραφικό το οποίο θα εμφανίζεται σαν γραφικό του προγράμματος στο task bar
  5. Πατάμε το tab “Σήματα” για να δώσουμε το όνομα της ρουτίνας που θα καλείται όταν ο χρήστης πατήσει το Χ κλεισίματος παραθύρου.
Πατώντας το Χ το Gtk στέλνει το σήμα destroy για την επικείμενη καταστροφή του παραθύρου.

Στο destroy του GtkObject δίνουμε σαν handler το close_window. Μην ανησυχείτε για αυτό ακόμα, θα γράψουμε την ρουτίνα αυτή μετά στο πρόγραμμα μας. Μπορείτε να της δώσετε ότι όνομα θέλετε αρκεί να χρησιμοποιήσετε το ίδιο και στο πρόγραμμα και στον handler.


Στην συνέχεια θα γεμίσουμε το παράθυρο μας με τα αντικείμενα που χρειαζόμαστε για το πρόγραμμα μας. Όταν ξεκινάμε μια γραφική εφαρμογή καλό θα είναι να έχουμε αποφασίσει τι αντικείμενα θέλουμε και να έχουμε σχεδιάσει το πως θα θέλαμε αυτά να εμφανιστούν στο παράθυρο. Στο Glade κάθε αντικείμενο καταλαμβάνει όλο τον χώρο μέσα στον container που βρίσκεται. Έτσι αν σε άδειο παράθυρο προσθέσουμε για παράδειγμα ένα label, αυτό θα καταλάβει όλο τον χώρο και δεν θα μπορούμε να προσθέσουμε τίποτα άλλο. Γι' αυτό και τα δύο πιο χρήσιμα container είναι το Vbox και το Hbox, κάθετος και οριζόντιος πίνακας αντίστοιχα.

  1. Ξεκινάμε με ένα Vbox. Κλικ στο εικονίδιο του και
  2. Κλικ στο παράθυρο
  3. Επιλέγουμε πόσες γραμμές θα έχει ο πίνακας, 6 εν προκειμένω, και
  4. Κλικ στο “Εντάξει”


Έχουμε τώρα το παράθυρο μας χωρισμένο σε 6 τμήματα. Σε καθένα από αυτά μπορούμε να προσθέσουμε ότι θέλουμε και αυτό θα καταλάβει μόνο το αντίστοιχο τμήμα.

Ξεκινάμε με το πάνω τμήμα να βάλουμε έναν οριζόντιο πίνακα τριών στηλών.
  1. Κλικ στο Hbox
  2. Κλικ στο πάνω τμήμα
  3. Δίνουμε 3 στήλες
  4. Πατάμε “Εντάξει”

Tο παράθυρο μας έχει τώρα την παρακάτω μορφή.


                  Στην συνέχεια επιλέγουμε ένα label για την πρώτη στήλη, ένα πεδίο εισόδου για την δεύτερη και ένα button για την τρίτη.

Η πρώτη γραμμή μας πρέπει τώρα να έχει αυτή την μορφή:  



Στην δεύτερη γραμμή προσθέτουμε έναν οριζόντιο πίνακα 3 τμημάτων. Στο πρώτο τμήμα βάζουμε ένα label, στο δεύτερο και τρίτο τμήμα από ένα button. Τώρα το παράθυρο μας έχει την εξής μορφή:    

 Πριν συνεχίσουμε λίγα λόγια για το πως διαχειρίζεται την τοποθέτηση και το μέγεθος των αντικείμενων το GTK. Κάνουμε κλικ στο hbox1 και μετά στο tab “packing”. H σειρά που θα εμφανιστεί κάθε αντικείμενο μέσα στο container του, καθορίζεται από την τιμή “Θέση”. Για το hbox1 έχει τιμή 0 γιατί το βάλαμε πρώτο στο vbox1 και γι' αυτό φαίνεται στην πρώτη γραμμή. Αν το αλλάξουμε και το κάνουμε 1 ή 2 ή 3 θα πάει στην αντίστοιχη γραμμή του vbox1. Το ίδιο ισχύει και για τα αντικείμενα του hbox1, τα label1, entry1, button1. Έχουν κι αυτά αντίστοιχα τιμές 0,1,2. Τα παρακάτω πεδία “Ανάπτυξη” και “Γέμισμα” που έχουν τιμή “Ναι” καθορίζουν το πως θα συμπεριφερθεί το αντικείμενο όταν ο χρήστης αλλάξει μέγεθος στο παράθυρο. Το “Ανάπτυξη” καθορίζει αν θα μεγαλώσει όσο μπορεί για να καλύψει τον έξτρα χώρο και το “Γέμισμα” αν θα γεμίσει ο χώρος με το αντικείμενο ή θα παραμείνει κενός. Ο “τύπος συσκευασίας”έχει τιμή “Έναρξη”, σημαίνει ότι η “Θέση”μετράει από την αρχή του container. Αν το αλλάξετε σε “τέλος” το hbox1 θα πάει στην τελευταία γραμμή και θα παραμείνει σε αυτήν ακόμα και αν εμείς προσθαφαιρέσουμε γραμμές στο vbox1. Το πεδίο “Γέμισμα” που δέχεται αριθμητική τιμή είναι πόσα pixel γύρω γύρω από το αντικείμενο θα υπάρχουν σαν περιθώριο του.

Αν κοιτάξουμε το “Packing” tab στα αντικείμενα μας θα δούμε ότι όλα έχουν “Ανάπτυξη” και “Γέμισμα” “Ναι”. Βάση των παραπάνω φανταζόμαστε ότι αν ο χρήστης μεγαλώσει το παράθυρο τα buttons θα γίνονται όλο και πιο χοντρά και μακριά το ίδιο και τα labels. To label2 δεν είναι στοιχισμένο κάτω από το label1 και όλο θα έρχεται πιο δεξιά αφού θα μεγαλώνει ο χώρος του. Μόνο το entry1 θέλουμε να μεγαλώνει για να δείχνει ολόκληρο κάποιο μεγάλο όνομα.

Πάμε λοιπόν να τα διαμορφώσουμε όπως θέλουμε.
Για αρχή κάνουμε κλικ στο παράθυρο μας και επιλέγουμε το tab “Κοινά” και βάζουμε τιμή 550 στην “Αίτηση πλάτους”. Αυτό θα μεγαλώσει όλο το παράθυρο μας και μπορεί να χαθεί τμήμα του πίσω από την δεξιά στήλη με τα αντικείμενα γι΄ αυτό ρυθμίζουμε ανάλογα το πλάτος της.
Στα hbox1 και hbox2 βάζουμε “Όχι” σε “Ανάπτυξη” και “Γέμισμα”. Στο label1 βάζουμε “Όχι” στην “Ανάπτυξη” και 5 στο “Γέμισμα”. Στο tab “Γενικά” βάζουμε 0 στην “Στοίχιση Χ” και σαν “Ετικέτα” βάζουμε: “Επιλογή XML αρχείου:” Στο label2: “Ανάπτυξη = Ναι”, “Γέμισμα = 5”, “Στοίχιση Χ = 0” και
Ετικέτα”  =  “Επιλογή εικόνων (*.jpg, *.png):”
Θα πρέπει τώρα το παράθυρο να έχει την εξής μορφή:



Στην συνέχεια αλλάζουμε το όνομα του entry1 σε xmlfile και αλλάζουμε το πεδίο “Παραμετροποιήσιμο” σε “Όχι” για να μην μπορεί ο χρήστης να γράψει με το χέρι, θα παίρνει τιμή από παράθυρο επιλογής αρχείων. 

Τα κουμπιά θέλουμε να είναι ομοιόμορφα για αυτό σε όλα στο tab “Κοινά” βάζουμε “Αίτηση πλάτους” 90 και στο tab “Packing” κάνουμε την “Ανάπτυξη” “Όχι”. Το button1 το μετονομάζουμε σε xmlbutton στο tab “Γενικά” και επιλέγουμε “Ετοιμο κουμπί (stock)” το gtk-open.


Επιλέγουμε gtk-open και στο button2 και το μετονομάζουμε σε “picbutton”. Το button3 το ονομάζουμε “clearbutton” και σαν περιεχόμενο διαλέγουμε το έτοιμο gtk-clear.

Μετά από αυτά πρέπει να έχουμε την εξής μορφή:


Να σώσουμε τώρα το αρχείο μας και να φτιάξουμε ένα πρόγραμμα σε python για να το εμφανίσουμε και να τεστάρουμε τις μεταβολές μεγεθών.
Σώζουμε το αρχείο σε έναν φάκελο της αρεσκείας μας με το όνομα backgroundxml.glade.
Σε έναν κειμενογράφο γράφουμε το εξής πρόγραμμα:
import gtk

class BackgroundXML(object):

def close_window(self, widget, data=None):
gtk.main_quit()

def __init__(self):
builder = gtk.Builder()
builder.add_from_file("backgroundxml.glade")
builder.connect_signals(self)
self.backgroundxml = builder.get_object("backgroundxml")

def main(self):
self.backgroundxml.show()
gtk.main()

if __name__ == "__main__":
app = BackgroundXML()
app.main()

Το σώζουμε στον ίδιο φάκελο με το αρχείο glade, με όνομα backgroundxml.py

Το τρέχουμε από την γραμμή εντολών με: python backgroundxml.py
Το αποτέλεσμα είναι:

Όπως βλέπουμε οι κενές γραμμές του vbox1 δεν εμφανίζονται και αν το μεγαλώσουμε τα στοιχεία μας παραμένουν ίδια σε μέγεθος και θέση, έκτος από το πεδίο εισαγωγής, και ο υπόλοιπος χώρος παραμένει κενός.


Με λίγες γραμμές κώδικα έχουμε έτοιμο το γραφικό μας περιβάλλον.
Λίγα λόγια για το πρόγραμμα.
Κάνουμε import το απαραίτητο gtk. Η κλάση BackgroundXML είναι η βασική του προγράμματος,
η οποία δημιουργεί το αντικείμενο app και στην συνέχεια καλούμε την main της κλάσης.
Για την δημιουργία του app η python χρησιμοποιεί την __init__ μέθοδο της κλάσης στην οποία φορτώνουμε το αρχείο glade με τον builder και συσχετίζουμε τα σήματα που έχουμε ορίσει με τις αντίστοιχες μεθόδους ( builder.connect_signals(self) ). Tην μεταβλητή self.backgroundxml την συσχετίζουμε με το αντικείμενο backgroundxml το οποίο είναι το βασικό μας παράθυρο.
Οπότε όταν καλούμε self.backgroundxml.show() στην main εμφανίζεται το παράθυρο μας και με την gtk.main() ο έλεγχος περνάει στο παράθυρο μέχρι αυτό να κλείσει. Το παράθυρο κλείνει όταν ο χρήστης πατήσει το Χ (μιας και δεν έχουμε βάλει button τέλους) και στέλνεται το σήμα destroy το οποίο έχουμε συνδέσει με την close_window η οποία καλεί την gtk.main_quit(). Ο έλεγχος επιστρέφει στο πρόγραμμα και αυτό, επειδή δεν έχει άλλη εντολή μετά την app.main(), τερματίζει.

Αυτός είναι ο βασικός κορμός ενός gtk προγράμματος. Το τελικό πρόγραμμα θα έχει πιο πολλά σήματα, μεθόδους και μεταβλητές αλλά πήραμε τώρα μια ιδέα για το πως γίνεται η διαδικασία.
Μπορείτε να πειραματιστείτε με τα αντικείμενα που έχουμε φτιάξει ήδη, αποκτώντας έτσι περισσότερη εμπειρία με το Glade και τις δυνατότητες του. Στο επόμενο άρθρο θα τελειώσουμε τον σχεδιασμό του παραθύρου μας και θα γνωρίσουμε νέα αντικείμενα.
Το άρθρο αυτό σε μορφή PDF, οι συλλήψεις οθόνης και τα αρχεία python και Glade μπορείτε να τα κατεβάσετε σε μορφή .tar.gz εδώ.

No comments:

Post a Comment