Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:prolog:prolog_lab:prolog_lab_xpce [2008/04/20 00:02] wojnicki xpce doc added |
pl:prolog:prolog_lab:prolog_lab_xpce [2019/06/27 15:50] (aktualna) |
Pełna dokumentacja XPCE znajduje się pod adresem: http://hcs.science.uva.nl/projects/xpce/UserGuide/ | Pełna dokumentacja XPCE znajduje się pod adresem: http://hcs.science.uva.nl/projects/xpce/UserGuide/ |
| |
===== Wprowadzenie ===== | ===== WPROWADZENIE ===== |
| |
| |
| |
==== Tworzenie obiektów ==== | ==== Tworzenie obiektów ==== |
new/2 (new(?Reference, +NewTerm)) umożliwia tworzenie obiektów graficznych, pierwszy argument zwraca referencje do utworzonego obieku (unikalny identyfikator) z użyciem @/1, drugi argument jest rodzajem obiektu (klasą) do utworzenia. | new/2 (new(?Reference, +NewTerm)) umożliwia tworzenie obiektów graficznych, pierwszy argument zwraca referencje do utworzonego obieku (unikalny identyfikator) z użyciem @/1, drugi argument jest rodzajem obiektu (klasą) do utworzenia. |
| |
| Referencje może być utworzona przez ''new'': |
<code prolog> | <code prolog> |
?- new(P, point(10,20)). | ?- new(P, point(10,20)). |
P = @772024 | P = @772024 |
| </code> |
| |
| Albo zadana (nazwana) tzw. //named reference//: |
| |
| <code prolog> |
?- new(@demo, dialog('Demo Window')). | ?- new(@demo, dialog('Demo Window')). |
</code> | </code> |
| |
free/1 (free(+Reference)) niszczy obiekty, argumentem jest identyfikator obiektu (pierwszy argument new/2). | free/1 (free(+Reference)) niszczy obiekty, argumentem jest identyfikator obiektu (pierwszy argument new/2). |
| |
| <code prolog> |
| ?- free(@demo). |
| </code> |
| |
| **Uwaga:** Wszystkie obiekty utworzone z wykorzysaniem //named reference// (@demo w powyższym przykładzie) muszą być usunięte za pomocą free/2 w celu uniknięcia wycieków pamięci. |
| Jeżeli referenca obiektu nie jest nazwana (pierwszy argument new jest szukaną), obiekty takie są automatycznie usuwane. |
| |
==== Modyfikacja stanu obiektów ==== | ==== Modyfikacja stanu obiektów ==== |
| |
?- send(@prolog, write('hello')). | ?- send(@prolog, write('hello')). |
| |
| |
| |
| |
uzgodni z szukaną ''X'' wartość wprowadzoną przez użytkownika. | uzgodni z szukaną ''X'' wartość wprowadzoną przez użytkownika. |
| |
| Poniższe zapytanie uzgodni szerokość ekranu z szukaną X: |
| |
?- get(@display,width,X). | ?- get(@display,width,X). |
W 9 lini występuje tzw. selektor. Pozwala on na wybranie określonej własności obiektu, która ma być przekazana. | W 9 lini występuje tzw. selektor. Pozwala on na wybranie określonej własności obiektu, która ma być przekazana. |
W tym przypadku jest to wartość ''selection'' pola tekstowego (szukana ''Txt''), czyli tekst wpisany w pole przez użytkownika. | W tym przypadku jest to wartość ''selection'' pola tekstowego (szukana ''Txt''), czyli tekst wpisany w pole przez użytkownika. |
| |
| **Uwaga:** Wszystkie referencje do obiektów (rezultaty predykatu new/2) w powyższym przykładzie tworzone są automatycznie (nie są to //named references//), nie trzeba stosować free/2, niszczeniem obiektów zajmie się garbage collector. |
| |
| |
| |
| ==== Okna modalne ==== |
| |
| Okno modalne jest to zwykle okno dialogowe, które blokuje wykonanie programu do czasu, aż użytkownik wprowadzi dane. |
| Aby skorzystać z mechanizmu blokowania należy użyć metod: ''confirm'' -- do wyświetlenia okna (zablokowania wykonania programu), oraz ''return'' do odblokowania. |
| |
| <code prolog> |
| zapytaj(Nazwa) :- |
| new(D, dialog('Podaj nazwe')), |
| send(D, append, |
| new(TI, text_item(nazwa, ''))), |
| send(D, append, |
| button(ok, message(D, return, |
| TI?selection))), % jeżeli przycisk nacisniety, odblokuj program |
| send(D, append, |
| button(porzuc, message(D, return, % jeżeli przycisk nacisniety, odblokuj program |
| @nil))), |
| send(D, default_button, ok), % Ok: domyslny przycisk |
| get(D, confirm, Odpowiedz), % wyswietlenie okna, zablokowanie wykonania programu |
| send(D, destroy), % analogiczne jak free(D) |
| Odpowiedz \== @nil, % uzytkonik nacisnal 'porzuc' |
| Nazwa = Odpowiedz. |
| </code> |
| |
| Zatem wykonując zapytanie: |
| |
| ?- zapytaj(X). |
| |
| zostanie wyświetlone okno dialogowe, gdy użytkownik wprowadzi nazwę i potwierdzi naciśnięciem przycisku ''ok'' wprowadzona nazwa zostanie uzgodniona z szukaną X. |
| |
| |
| ==== Obiekty graficzne ==== |
| |
| XPCE umożliwia wyświetlanie i manipulacje obiektów graficznych takich jak: strzałki, krzywe bezier, mapy bitowe, prostokąty, okręgi, elipsy, łuki, linie, łamane, oraz tekst. |
| |
| Do wyświetlania obiektów graficznych często wykorzystywana jest klasa ''window'' albo ''picture'' (dodaje suwaki). |
| Przykładowo: |
| <code prolog> |
| ?- new(@p, picture('Demo Picture')), send(@p, open). |
| |
| ?- send(@p, display, |
| new(@bo, box(100,100))). |
| ?- send(@p, display, |
| new(@ci, circle(50)), point(25,25)). |
| ?- send(@p, display, |
| new(@bm, bitmap('32x32/books.xpm')), point(100,100)). |
| ?- send(@p, display, |
| new(@tx, text('Hello')), point(120, 50)). |
| ?- send(@p, display, |
| new(@bz, bezier_curve(point(50,100), |
| point(120,132), |
| point(50, 160), |
| point(120, 200)))). |
| </code> |
| |
| Modyfikacje obiektów: |
| |
| <code prolog> |
| ?- send(@bo, radius, 10). |
| ?- send(@ci, fill_pattern, colour(orange)). |
| ?- send(@tx, font, font(times, bold, 18)). |
| ?- send(@bz, arrows, both). |
| </code> |
| |
| |
| |
| ==== Obiekty złożone i połączone ==== |
| |
| Obiekty graficzne można ze sobą połączyć tworząc grupę obiektów (obiekt złożony) i wykonywać transformacje (zmiana koloru, położenia etc.) na całej grupie np: |
| |
| <code prolog> |
| ?- new(@ic, device), |
| send(@ic, display, bitmap('happy.bm')), |
| send(@ic, display, text('Happy'), point(0, 64)), |
| send(@p, display, @ic, point(250, 20)). |
| </code> |
| |
| Następnie można przesunąć całą grupę: |
| |
| <code prolog> |
| ?- send(@ic,x,100), send(@ic,y,120). |
| </code> |
| |
| Obiekty również można ze sobą połączyć, tak aby modyfikacja jednego obiektu pociągała za sobą modyfikację innego. Przykład znajduje się w następnej sekcji. |
| |
| ==== Mysz: interakcja z obiektami graficznymi ==== |
| |
| Poniższy przykład umożliwia połączenie zdarzenia polegającego na przesunięciu obiektu mysza (przytrzymując lewy przycisk) z obiektem identyfikowanym przez @ic. |
| |
| <code prolog> |
| ?- send(@ic, recogniser, move_gesture(left)). |
| </code> |
| |
| Albo co ma się stać po dwukrotnym kliknięciu obiektu @ci: |
| |
| <code prolog> |
| ?- send(@ci, recogniser, |
| click_gesture(left, '', double, |
| message(@pce, write_ln, hello))). |
| </code> |
| |
| Poniższy przykład ilustruje tworzenie i manipulację obiektów połączonych. |
| |
| <code prolog> |
| :- pce_global(@in_out_link, make_in_out_link). |
| |
| make_in_out_link(L) :- |
| new(L, link(in, out, line(arrows := second))). |
| |
| linked_box_demo :- |
| new(P, picture('Linked Box demo')), |
| send(P, open), |
| send(P, display, new(B1, box(50,50)), point(20,20)), |
| send(P, display, new(B2, box(25,25)), point(100,100)), |
| send(B1, handle, handle(w, h/2, in)), |
| send(B2, handle, handle(w/2, 0, out)), |
| send_list([B1, B2], recogniser, new(move_gesture(left))), |
| send(B1, connect, B2, @in_out_link). |
| </code> |
| |
| ===== ĆWICZENIA ===== |
| |
| |
| |
| |
| ==== 1 Ćwiczenie: Okno dialogowe ==== |
| |
| Przetestuj poniższy program ((przykład zaczerpnięty z http://hcs.science.uva.nl/projects/xpce/UserGuide/sec-4.1.html)). ''send_list'' działa podobnie jak ''send'' przu czym uruchamia wskazaną metodę z argumentami będącymi kolejnymi elementami listy. Pojedynczy predykat ''send_list'' zastępuje wiele predykatów ''send''. |
| |
| <code prolog> |
| :-dynamic(employee/2). |
| |
| ask_employee :- |
| new(Dialog, dialog('Define employee')), |
| send_list(Dialog, append, |
| [ new(N1, text_item(first_name)), |
| new(N2, text_item(family_name)), |
| new(S, new(S, menu(sex))), |
| new(A, int_item(age, low := 18, high := 65)), |
| new(D, menu(department, cycle)), |
| button(cancel, message(Dialog, destroy)), |
| button(enter, and(message(@prolog, |
| assert_employee, |
| N1?selection, |
| N2?selection, |
| S?selection, |
| A?selection, |
| D?selection), |
| message(Dialog, destroy))) |
| ]), |
| send_list(S, append, [male, female]), |
| send_list(D, append, [research, development, marketing]), |
| send(Dialog, default_button, enter), |
| send(Dialog, open). |
| |
| assert_employee(FirstName, FamilyName, Sex, Age, Dept) :- |
| assert(employee(FirstName, FamilyName, Sex, Age, Dept)). |
| </code> |
| |
| ==== 2 Ćwiczenie: Okno dialogowe ==== |
| |
| Rozbuduj program z Ćwiczenia 1. |
| Dopisz redykat ''show_employees/0'' umożliwiający przeglądanie danych pochodzących z ''employee/5''. |
| W celu znalezienia odpowiednich obiektów wyświetlających dane tekstowe zobacz: [[http://hcs.science.uva.nl/projects/xpce/UserGuide/|Programming in XPCE]]. |
| |
| |
| ==== 3 Ćwiczenie: Okna modalne ==== |
| |
| Dany jest następujący kod uzupełniający przykłady z rodziny wzięte: |
| |
| <code prolog> |
| go :- kobieta(X), wyswietl(X). |
| go. |
| </code> |
| |
| Zaprogramuj predykat wyświetl, tak aby wyświetlał w oknie dialogowym 1-szy argument oraz dwa przycski: ''Koniec'', ''Nastepny''. |
| Okno dilogowe powinno blokować wykonanie programu, aż do naciśnięcia jednego z przycisków. |
| Przy naciśnięciu ''Nastepny'' predykat zwraca fałsz wymuszając nawrót, dla ''Koniec'' zwraca prawdę. |
| |
| ==== 4 Ćwiczenie: Wizualizacja drzewa genealogicznego potomków ==== |
| |
| Korzystając z predykatów określających koligacje rodzinne z [[prolog lab 1]] oraz z XPCE napisz predykat generujący graf będący drzewem genealogicznym określającym potomków wskazanej osoby: |
| |
| rysuj_potomek(+Kto,+Rodzic,+Kobieta,+Mezczyzna) |
| |
| gdzie Kto to osoba, dla której zostanie wygenerowane drzewo potomków, pozostałe argumenty są nazwami predykatów określającymi odpowiednio kto jest czyim rodzicem, kto jest kobietą, kto jest mężczyzną. |
| Przykładowe wywołanie: |
| |
| rysuj_potomek(franek,rodzic/2,kobieta/1,mezczyzna/1) |
| |
| Wygeneruje drzewo genealogiczne potomków dla osoby franek, przy czym rodzic/2, kobieta/1, mezczyzna/1 są zdefinowanymi predykatami, których klauzule przechowują informacje o koligacjach rodzinnych. |
| |
| Podpowiedź: najpierw napisz predykat znajdujący potomków, potem dodaj generację danych dla [[misc:GraphViz]], następnie wizualizację. |
| |
| ==== 5 Ćwiczenie: Wizualizacja drzewa genealogicznego ==== |
| |
| Napisz predykat: |
| |
| rysuj_drzewo(+Kto,+Rodzic,+Kobieta,+Meżczyzna) |
| |
| rysujący kompletne drzewo dla wskazanej osoby. |
| |
| Przykład drzewa genealogicznego: |
| |
| {{:pl:prolog:prolog_lab:drzewo_gen_przyklad.png}} |
| |
| |
| ==== Ćwiczenie 6: Obiekty graficzne ==== |
| |
| TBD |
| |
| ====== Uwagi, komentarze, propozycje ====== |
| Tu studenci mogą wpisywać swoje uwagi. |
| |
| --- //[[gjn@agh.edu.pl|Grzegorz J. Nalepa]] 2009/05/06 09:13// |
| |
| Wg. mnie trochę za dużo materiału - mi się udało na zajęciach zrobić tylko 3 pierwsze ćwiczenia. |
| |
| --- //Tomek Kozera 2009/05/16 21:01// |
| |
| "Jeżeli referenca obiektu nie" Literówka - referencja powinno być |
| |
| "Referencje może być utworzona przez new:" - jak wyżej |
| |
| "działa podobnie jak send przu czym" - znowu literówka ;) |
| |
| ---Anonim |
| "send można również dekomponując term, zatem powyższy przykład można zapisać jako:" -- jakiś błąd logiczny, brakuje co najmniej jednego słowa ("send można użyć(?)") -- Kamil Kuduk |