2D σε μια οθόνη: καμβάδες GUI#
Όλα ως τώρα σχεδίαζαν σε ένα αρχείο. Αυτό το κεφάλαιο σχεδιάζει σε ένα παράθυρο: έναν διαδραστικό καμβά που ξαναβάφεται, ανταποκρίνεται στο ποντίκι και στο πληκτρολόγιο, και μπορεί να κινείται. Κάθε εργαλειοθήκη GUI λειτουργεί με τον ίδιο τρόπο σε γενικές γραμμές: δημιουργείτε ένα παράθυρο, του δίνετε έναν χειριστή βαφής που σχεδιάζει το περιεχόμενό του, και η εργαλειοθήκη καλεί αυτόν τον χειριστή όποτε το παράθυρο χρειάζεται επανασχεδίαση. Η σχεδίαση μέσα στον χειριστή χρησιμοποιεί πρωτογενή που είναι πλέον οικεία: γραμμές, ελλείψεις, πολύγωνα, γεμίσματα.
Το τοπίο των GUI της Perl έχει μια σαφή καλύτερη επιλογή για γραφικά και αρκετές άλλες με συμβιβασμούς. Αυτό το κεφάλαιο ξεκινά με το Prima, γιατί συντηρείται ενεργά, είναι αυτοτελές, και έχει έναν πραγματικό πυρήνα γραφικών· έπειτα καλύπτει τα Tk και Gtk3 για όταν έχετε λόγο να τα προτιμήσετε· και είναι ειλικρινές για το Wx, που δεν είναι πλέον μια υγιής επιλογή.
Prima: η αυτοτελής επιλογή#
Το Prima είναι μια εργαλειοθήκη GUI γραμμένη για την Perl με τη δική της μηχανή γραφικών. Δεν τυλίγει μια εξωτερική εργαλειοθήκη που πρέπει να εγκαταστήσετε και να ταιριάξετε εκδόσεις μαζί της· σχεδιάζει εγγενώς (στο X11 στο Linux) και αποστέλλει τα δικά του πρωτογενή, χειρισμό εικόνας και γραμματοσειρές. Συντηρείται, και είναι η σύσταση για νέα δουλειά GUI με πολλά γραφικά στην Perl.
Ένα ελάχιστο παράθυρο με έναν χειριστή βαφής:
use Prima qw(Application);
my $win = Prima::MainWindow->new(
text => 'Prima demo',
size => [400, 300],
onPaint => sub {
my ($self, $canvas) = @_; # the handler gets a canvas
$canvas->color(cl::White);
$canvas->bar(0, 0, $canvas->size); # bar is a filled rectangle
$canvas->color(cl::Red);
$canvas->fill_ellipse(200, 150, 120, 90);
$canvas->color(cl::Black);
$canvas->line(0, 0, 400, 300);
},
);
Prima->run;
Δύο σημειώσεις ονοματοδοσίας που παγιδεύουν τους νεοφερμένους. Το γεμάτο ορθογώνιο του Prima είναι το bar· το σκέτο rectangle σχεδιάζει το περίγραμμα. Το γέμισμα πολυγώνου είναι το fillpoly (μία λέξη), που παίρνει μια αναφορά πίνακα συντεταγμένων. Τα χρώματα προέρχονται από τις σταθερές cl:: (cl::Red, cl::White κ.ο.κ.) ή από έναν πακεταρισμένο ακέραιο RGB, και ορίζονται ως η κατάσταση σχεδίασης με το color πριν σχεδιάσετε, αντί να περνιούνται σε κάθε πρωτογενές.
Τα πρωτογενή του Prima::Drawable είναι το πλήρες σύνολο που περιμένετε: line, ellipse και fill_ellipse, arc, sector και fill_sector, polyline, fillpoly, bar, rectangle, flood_fill, και put_image για blit ενός bitmap. Η κατάσταση σχεδίασης περιλαμβάνει τα color, backColor, lineWidth και μοτίβα γεμίσματος.
Σχεδίαση εκτός οθόνης και αποθήκευση#
Τα ίδια πρωτογενή λειτουργούν σε ένα Prima::Image, μια επιφάνεια εκτός οθόνης, οπότε μπορείτε να σχεδιάσετε χωρίς παράθυρο και να αποθηκεύσετε το αποτέλεσμα. Έτσι ένα πρόγραμμα Prima εξάγει αυτό που σχεδίασε:
my $img = Prima::Image->new(width => 200, height => 200, type => im::RGB);
$img->begin_paint;
$img->color(cl::Blue);
$img->fill_ellipse(100, 100, 80, 80);
$img->end_paint;
$img->save('out.png');
Τα begin_paint και end_paint περικλείουν τη σχεδίαση πάνω στην εικόνα εκτός οθόνης, και το save τη γράφει σε μια μορφή που συμπεραίνεται από την επέκταση. Αυτή η διττή φύση (ίδιος κώδικας σχεδίασης για την οθόνη και για ένα αρχείο) είναι ο λόγος για τον οποίο τα ολοκληρωτικά κεφάλαια χτίζουν πάνω στο Prima.
Tk: ο κλασικός Canvas#
Το Tk (Perl/Tk) είναι η μακροχρόνια επιλογή, και το widget Canvas του έχει ένα διαφορετικό μοντέλο που αξίζει να γνωρίζετε: είναι retained-mode. Αντί για έναν χειριστή βαφής που ξανασχεδιάζει τα πάντα, δημιουργείτε αντικείμενα καμβά (μια γραμμή, ένα οβάλ, ένα πολύγωνο) που το widget θυμάται και ξανασχεδιάζει για εσάς, και τα μετακινείτε ή τα αναδιαμορφώνετε με το id τους. Αυτό ταιριάζει σε διαγράμματα και επεξεργαστές όπου τα αντικείμενα διατηρούνται και υφίστανται χειρισμό.
use Tk;
my $mw = MainWindow->new;
my $canvas = $mw->Canvas(-width => 400, -height => 300)->pack;
$canvas->createLine(0, 0, 400, 300, -fill => 'blue', -width => 2);
my $oval = $canvas->createOval(160, 100, 240, 180, -fill => 'red');
$canvas->createPolygon(50, 10, 150, 10, 100, 90, -fill => 'green');
# move the remembered oval later, by id
$canvas->move($oval, 20, 0);
MainLoop;
Το Tk είναι σταθερό και λειτουργεί, αν και βρίσκεται σε συντήρηση αντί για ενεργή ανάπτυξη και κουβαλά μερικά κληρονομημένα CVE στο ενσωματωμένο Tcl/libpng του. Για ένα διάγραμμα με μόνιμα αντικείμενα ή ένα γρήγορο κλασικό GUI είναι μια λογική επιλογή· για μια κίνηση με επανασχεδίαση σε κάθε καρέ το μοντέλο immediate-mode του Prima ταιριάζει καλύτερα.
Gtk3: σχεδίαση μέσω Cairo#
Το Gtk3 συνδέει το GTK 3 μέσω introspection του GObject. Η ιστορία σχεδίασής του είναι ότι ένα widget Gtk3::DrawingArea εκπέμπει ένα σήμα draw στο οποίο δίνεται ένα context Cairo, οπότε σχεδιάζετε με το API του Cairo από το κεφάλαιο των vector μέσα στον χειριστή. Αν η εφαρμογή σας είναι ήδη μια εφαρμογή GTK, αυτός είναι ο φυσικός τρόπος να προσθέσετε προσαρμοσμένα γραφικά· αν δεν είναι, το να τραβήξετε μέσα ολόκληρη τη στοίβα GTK (τις βιβλιοθήκες ανάπτυξης του GTK 3 και τα δεδομένα introspection του GObject) είναι μια μεγάλη εξάρτηση μόνο για γραφικά.
use Gtk3 -init;
my $window = Gtk3::Window->new('toplevel');
my $area = Gtk3::DrawingArea->new;
$window->add($area);
$window->set_default_size(400, 300);
$area->signal_connect(draw => sub {
my ($widget, $cr) = @_; # $cr is a Cairo context
$cr->set_source_rgb(0.2, 0.4, 0.9);
$cr->arc(200, 150, 80, 0, 6.28318);
$cr->fill;
return 0;
});
$window->show_all;
Gtk3->main;
Όλα όσα ξέρετε για το Cairo ισχύουν αμετάβλητα μέσα σε αυτόν τον χειριστή. Το Gtk3 είναι χρησιμοποιήσιμο αλλά σε αργή συντήρηση, και το βάρος των εξαρτήσεων σημαίνει ότι κερδίζει τη θέση του κυρίως όταν το GTK είναι ήδη στην εικόνα.
Wx: αναφορά, όχι σύσταση#
Θα βρείτε το Wx (wxPerl) να αναφέρεται ως ο τρόπος να χτίσετε cross-platform GUI με εγγενή εμφάνιση στην Perl, και ιστορικά ήταν. Περιλαμβάνεται εδώ ώστε να είναι σαφής η τρέχουσα κατάστασή του: το Wx και η εξάρτηση κατασκευής του Alien::wxWidgets δεν έχουν κυκλοφορήσει έκδοση εδώ και χρόνια, και ένα μεγάλο ποσοστό των αυτοματοποιημένων αναφορών κατασκευής αποτυγχάνει έναντι του τρέχοντος wxWidgets. Δεν είναι επιλογή για νέα δουλειά. Αν χρειάζεστε ένα GUI με προσαρμοσμένη σχεδίαση σήμερα, το Prima είναι η συντηρούμενη αυτοτελής επιλογή και το Tk το συντηρούμενο κλασικό· καταφύγετε σε ένα από αυτά τα δύο αντ” αυτού.
Επιλογή#
Θέλετε … | Καταφύγετε σε |
|---|---|
Συντηρούμενο, αυτοτελές, νέο GUI με πολλά γραφικά |
|
Έναν καμβά retained-mode με μόνιμα αντικείμενα |
|
Προσαρμοσμένη σχεδίαση μέσα σε μια υπάρχουσα εφαρμογή GTK |
|
Κίνηση ανά καρέ και έναν βρόχο πραγματικού χρόνου |
|
Με ένα παράθυρο και έναν χειριστή βαφής στα χέρια, ο άξονας των εργαλειοθηκών ολοκληρώνεται. Ο επόμενος άξονας πηγαίνει πιο μακριά από οποιοδήποτε μεμονωμένο άρθρωμα του CPAN: χρησιμοποιεί το εγγενές FFI της pperl για να προσεγγίσει βιβλιοθήκες γραφικών C απευθείας, και έπειτα ξοδεύει όλα όσα υπάρχουν στον οδηγό σε δύο έργα που μπορείτε να εκτελέσετε, χτισμένα και τα δύο πάνω στο θεμέλιο του Prima από αυτό το κεφάλαιο.