דו־ממד על מסך: קנבסים של 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) היא האפשרות הוותיקה, ולווידג’ט ה־Canvas שלה יש מודל שונה שכדאי להכיר: הוא מצב־מוחזק (retained-mode). במקום מטפל צביעה המצייר הכול מחדש, אתם יוצרים פריטי קנבס (קו, סגלגל, מצולע) שהווידג’ט זוכר ומצייר מחדש עבורכם, ואתם מזיזים או מגדירים אותם מחדש לפי המזהה שלהם. זה מתאים לתרשימים ולעורכים שבהם אובייקטים נמשכים ומטופלים.
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 יציבה ועובדת, אף שהיא בתחזוקה ולא בפיתוח פעיל ונושאת כמה CVEs שירשה ב־Tcl/libpng המצורפים לה. לתרשים בעל־אובייקטים־נמשכים או ל־GUI קלאסי מהיר זו בחירה סבירה; לאנימציה של ציור־מחדש־בכל־מסגרת מודל Prima של מצב־מיידי מתאים יותר.
Gtk3: ציור דרך Cairo#
Gtk3 כורכת את GTK 3 דרך אינטרוספקציה של GObject. סיפור הציור שלה הוא שווידג’ט Gtk3::DrawingArea פולט אות draw שנמסר לו הקשר Cairo, כך שאתם מציירים עם ה־API של Cairo מפרק הווקטור בתוך המטפל. אם היישום שלכם כבר יישום GTK, זו הדרך הטבעית להוסיף גרפיקה מותאמת; אם לא, משיכת כל מחסנית GTK פנימה (ספריות הפיתוח של GTK 3 ונתוני האינטרוספקציה של 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) מוזכרת כדרך לבנות ממשקי GUI חוצי־פלטפורמה בעלי מראה מובנה ב־Perl, ומבחינה היסטורית כך היה. היא נכללת כאן כדי שמצבה הנוכחי יהיה ברור: ל־Wx ולתלות הבנייה Alien::wxWidgets שלה לא הייתה מהדורה שנים, וחלק גדול מדוחות הבנייה האוטומטיים נכשל מול wxWidgets הנוכחי. היא אינה בחירה לעבודה חדשה. אם אתם זקוקים ל־GUI עם ציור מותאם היום, Prima היא האפשרות העצמאית המתוחזקת ו־Tk הקלאסי המתוחזק; פנו לאחת מאלה במקום.
בחירה#
אתם רוצים … | פנו אל |
|---|---|
GUI חדש מתוחזק, עצמאי, עתיר־גרפיקה |
|
קנבס במצב־מוחזק של אובייקטים נמשכים |
|
ציור מותאם בתוך יישום GTK קיים |
|
אנימציה לכל־מסגרת ולולאת זמן־אמת |
|
עם חלון ומטפל צביעה ביד, קשת ערכות הכלים שלמה. הקשת הבאה הולכת רחוק יותר מכל מודול CPAN יחיד: היא משתמשת ב־FFI המובנה של pperl כדי להגיע ישירות לספריות גרפיקה של C, ואז מוציאה את כל מה שבמדריך על שני פרויקטים שאפשר להריץ, שניהם בנויים על יסוד Prima מפרק זה.