Susanna Huhtanen ihmis.suski@gmail.com 2012 Ελληνική μεταφραστική ομάδα GNOME team@gnome.gr 2012-2015 Δημήτρης Σπίγγος dmtrs32@gmail.com 2012, 2013 Μαρία Θουκιδίδου marablack3@gmail.com 2014 Θάνος Τρυφωνίδης tomtryf@gmail.com 2014, 2015 Το κύριο αρχείο του προγράμματος

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

Σενάριο για εκτέλεση της εφαρμογής

Βιβλιοθήκες για εισαγωγή

Δημιουργία του κύριου παραθύρου για την εφαρμογή

Προσθήκη πλέγματος και όλων των απαραίτητων γραφικών στοιχείων σε αυτό

Αίτηση των πληροφοριών καιρού ασύγχρονα

Σύνδεση σημάτων σε κουμπί και καταχώριση.

weatherapp.js

Σενάριο για εκτέλεση της εφαρμογής #!/usr/bin/gjs

Αυτή η γραμμή λέει πώς θα εκτελεστεί το σενάριο. Πρέπει να είναι η πρώτη γραμμή του κώδικα και να είναι εκτελέσιμη. Για λήψη των δικαιωμάτων εκτέλεσης πηγαίνετε στον τερματικό και εκτελέστε στον σωστό φάκελο: chmod +x όνομα σεναρίου. Ή μπορείτε να χρησιμοποιήσετε τον διαχειριστή αρχείου γραφικών. Απλά πηγαίνετε στον σωστό φάκελο όπου είναι ο κώδικας σας δεξί κλικ στο αρχείο του κώδικα σας, επιλέξτε ιδιότητες, κλικ στην καρτέλα δικαιωμάτων και σημειώστε το πλαίσιο για να επιτραπεί η εκτέλεση του αρχείου ως πρόγραμμα

Βιβλιοθήκες για εισαγωγή var Gtk = imports.gi.Gtk; const WeatherService = imports.geonames;

Για να έχουμε ένα αποτελεσματικό πρόγραμμα χρειαζόμαστε να εισάγουμε μια βιβλιοθήκη GObject αυτανάλυσης για χρήση. Για χρήση UI, χρειαζόμαστε Gtk. Το Gtk εισάγεται στην αρχή, έτσι το έχουμε για χρήση παντού. Εισάγουμε επίσης τη δικιά μας τοπική βιβλιοθήκη JavaScript geonames για να χρησιμοποιηθεί εδώ.

Δημιουργία του κύριου παραθύρου για την εφαρμογή // Αρχικοποίηση της gtk Gtk.init(null, 0); //Δημιουργία του παραθύρου σας, ονομασία του και σύνδεσή του x με τη συνάρτηση εξόδου. Να θυνάστε ότι το παράθυρο είναι μια δεδομένη λέξη var weatherwindow = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL}); weatherwindow.title = "Todays weather"; //Το παράθυρο δέχεται μόνο ένα γραφικό στοιχείο και έναν τίτλο. Παραπέρα δομή με παρόμοια Gtk.boxes weatherwindow.connect("destroy", function(){Gtk.main_quit()}); weatherwindow.show_all(); //και εκτέλεσή του Gtk.main();
Προσθήκη πλέγματος και όλων των απαραίτητων γραφικών στοιχείων σε αυτό var grid = new Gtk.Grid(); weatherwindow.add(grid); //Αρχικοποιούμε εδώ το εικονίδιο, αλλά αποφασίζει το αρχείο αργότερα στο geonames.js. var weatherIcon = new Gtk.Image(); //Ορισμός μερικών ετικετών στο παράθυρό σας var label1 = new Gtk.Label({label: ""}); var label2 = new Gtk.Label({label: "Looking in the sky..."}); var label3 = new Gtk.Label({label: ""}); var entry = new Gtk.Entry(); entry.set_width_chars(4); entry.set_max_length(4); var label4 = new Gtk.Label({label: "Enter ICAO station for weather: "}); var button1 = new Gtk.Button({label: "search!"}); grid.attach(label4, 2, 1, 1, 1); grid.attach_next_to(label1,label4,3,1,1); grid.attach_next_to(label2,label1,3,1,1); grid.attach_next_to(label3,label2,3,1,1); grid.attach_next_to(entry,label4,1,1,1); grid.attach_next_to(button1,entry,1,1,1); grid.attach_next_to(weatherIcon,label2,1,1,1)

In this section we create the grid we are going to use for positioning the widgets. All the buttons, labels and entries are initialized and placed on the grid. As seen from the placing of the different widgets, they don't need to be related only to one widget. At this point some of the labels don't have any content. The content for those widgets is applied later. If you run the application at this stage, you have the UI ready, but the widgets are not connected to anything. For this we need to first build the weather searching local library, and then get the information we need asynchronously. When we have our local library ready we can connect it to the necessary widgets.

Αίτηση των πληροφοριών καιρού ασύγχρονα function getWeatherForStation() { var station = entry.get_text(); var GeoNames = new WeatherService.GeoNames(station); //"EFHF"; GeoNames.getWeather(function(error, weather) { //Αυτό εδώ δουλεύει λίγο σαν σήματα. Αυτός ο κώδικας θα εκτελεστεί όταν έχουμε καιρό. if (error) { label2.set_text("Suggested ICAO station does not exist Try EFHF"); return; } weatherIcon.file = GeoNames.getIcon(weather); label1.set_text("Temperature is " + weather.weatherObservation.temperature + " degrees."); if (weather.weatherObservation.weatherCondition !== "n/a"){ label2.set_text("Looks like there is " + weather.weatherObservation.weatherCondition + " in the sky."); } else { label2.set_text("Looks like there is " + weather.weatherObservation.clouds + " in the sky."); } label3.set_text("Windspeed is " + weather.weatherObservation.windSpeed + " m/s") // ... }); }

Αυτή η λειτουργία αφιερώνεται στην κλήση για τις πληροφορίες καιρού και ενημέρωση ετικετών και εικονιδίων ανάλογα. Στην αρχή της λειτουργίας παίρνουμε την είσοδο χρήστη για αναζήτηση. Έτσι εδώ για την πρώτη φορά χρησιμοποιούμε τη δική μας βιβλιοθήκη και τις αποδίδουμε τη μεταβλητή GeoNames. Ενώ εκχωρούμε την WeatherService της δίνουμε τον σταθμό. Το πρώτο πράγμα που κάνουμε με τα GeoNames είναι η αίτηση καιρού. Οτιδήποτε μετά τα GeoNamesgetWeather.getWeather (συνάρτηση (σφάλμα, καιρός) συμβαίνει μόνο εάν είτε πάρουμε ένα μήνυμα σφάλματος ή πληροφορίες καιρού. Εάν δεν έρθει κανένα, το υπόλοιπο του προγράμματος δουλεύει τόσο κανονικά, όσο το main_Quit δουλεύει.

Σύνδεση σημάτων σε κουμπί και καταχώριση. entry.connect("key_press_event", function(widget, event) { if (entry.get_text().length === 4) { // Enough is enough getWeatherForStation(); } return false; }); button1.connect("clicked", function(){ getWeatherForStation(); });

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

Weatherapp.js

Το αρχείο Weatherapp.js μοιάζει με αυτό:

#!/usr/bin/gjs //Η προηγούμενη γραμμή αρχίζει με δίεση-θαυμαστικό που λέει π να εκτελεστεί το σενάριο. // Σημειώστε ότι το σενάριο πρέπει να είναι εκτελέσιμο (εκτέλεση σε τερματικό στον δεξιό φάκελο: chmod +x scriptname) var Gtk = imports.gi.Gtk; const WeatherService = imports.geonames; //Μεταφορά της δικής σας βιβλιοθήκης από τον ίδιο φάκελο (όπως ορίστηκε στο GJS_PATH). Αν χρησιμοποιείτε autotools .desktop θα φροντίσει για αυτό // Αρχικοποίηση της gtk Gtk.init(null, 0); //Δημιουργία του παραθύρου σας, ονομασία του, και σύνδεση του x με τη συνάρτηση εξόδου. Να θυμάστε ότι το παράθυρο είναι μια δεσμευμένη λέξη var weatherwindow = new Gtk.Window({type: Gtk.WindowType.TOPLEVEL}); weatherwindow.title = "Todays weather"; //Το παράθυρο δέχεται μόνο ένα γραφικό στοιχείο και έναν τίτλο. Παραπέρα δομή όμοια μεGtk.boxes weatherwindow.connect("destroy", function(){Gtk.main_quit()}); //We initialize the icon here, but deside the file later in geonames.js. var weatherIcon = new Gtk.Image(); //Ορισμός μερικών ετικετών στο παράθυρό σας var label1 = new Gtk.Label({label: ""}); var label2 = new Gtk.Label({label: "Looking in the sky..."}); var label3 = new Gtk.Label({label: ""}); var grid = new Gtk.Grid(); weatherwindow.add(grid); var entry = new Gtk.Entry(); entry.set_width_chars(4); entry.set_max_length(4); var label4 = new Gtk.Label({label: "Enter ICAO station for weather: "}); var button1 = new Gtk.Button({label: "search!"}); //Κάποιος καιρός entry.connect("key_press_event", function(widget, event) { // FIXME: Λήψη καιρού με την εισαγωγή (πλήκτρο 13) if (entry.get_text().length === 4) { // Enough is enough getWeatherForStation(); } return false; }); button1.connect("clicked", function(){ getWeatherForStation(); }); function getWeatherForStation() { var station = entry.get_text(); var GeoNames = new WeatherService.GeoNames(station); //"EFHF"; GeoNames.getWeather(function(error, weather) { //Αυτό εδώ δουλεύει λίγο σαν σήματα. Αυτός ο κώδικας θα εκτελεστεί όταν έχουμε καιρό. if (error) { label2.set_text("Suggested ICAO station does not exist Try EFHF"); return; } weatherIcon.file = GeoNames.getIcon(weather); label1.set_text("Temperature is " + weather.weatherObservation.temperature + " degrees."); if (weather.weatherObservation.weatherCondition !== "n/a"){ label2.set_text("Looks like there is " + weather.weatherObservation.weatherCondition + " in the sky."); } else { label2.set_text("Looks like there is " + weather.weatherObservation.clouds + " in the sky."); } label3.set_text("Windspeed is " + weather.weatherObservation.windSpeed + " m/s") // ... }); } grid.attach(label4, 2, 1, 1, 1); grid.attach_next_to(label1,label4,3,1,1); grid.attach_next_to(label2,label1,3,1,1); grid.attach_next_to(label3,label2,3,1,1); grid.attach_next_to(entry,label4,1,1,1); grid.attach_next_to(button1,entry,1,1,1); grid.attach_next_to(weatherIcon,label2,1,1,1) weatherwindow.show_all(); //και εκτέλεσή του Gtk.main();

Εκτέλεση μέχρι να έχετε όλα τα αρχεία autotools έτοιμα. :

$ GJS_PATH=`pwd` gjs weatherapp.js

Χρησιμοποιήστε αυτήν την εντολή στο τερματικό ενώ αναπτύσσετε τα αρθρώματά σας. Όταν καλείτε το πρόγραμμά σας με αυτόν τον τρόπο, ξέρει πού θα βρει τις προσαρμοσμένες JSlibraries, σε αυτήν την περίπτωση το geonames.js.