Z rozmów z początkującymi użytkownikami MorphOS-a wiem, że dużo osób, próbując pisać swoje pierwsze aplikacje, zraziło się do języka C i drzewiastych struktur MUI. Jeżeli jesteś jedną z nich, mam dla Ciebie dobrą wiadomość - z PyMUI pokochasz tworzenie okienkowych aplikacji. A co to jest? Jest to pakiet dla języka Python, który pozwala tworzyć interfejsy użytkownika przy pomocy środowiska MUI. Z samym MUI każdy, nawet początkujący amigowiec, powinien spotkać się wielokrotnie. Jeżeli jednak słyszysz o MUI pierwszy raz, polecam odwiedzić stronę autora http://www.sasg.com/mui/ i przeczytać przynajmniej opis tego interfejsu użytkownika. Co do samego Pythona instalację i lekcję wprowadzającą zrobił Marek Hać w poprzednim numerze naszego magazynu, a więc ten temat skrzętnie pominę.
Dlaczego w Pythonie, a nie w C?
Oprócz prostoty tworzenia okien jest jeszcze parę innych aspektów, w których Python przeważa nad C. Dzięki nim polubisz i szybko przyswoisz pracę z Pythonem. Oto kilka z nich:
Jest jeden mały minus - program jest trochę wolniejszy niż jego odpowiednik napisany w C, ale przy obecnych prędkościach procesorów PPC w PowerMacach i Macach Mini nie stanowi to dużego problemu.
Zaczynamy
Zgodnie ze wstępem zakładam, że mamy już zainstalowanego Pythona przynajmniej w wersji 2.5.4. Pobieramy pakiet PyMUI do ze strony autora. Rozpakowujemy i instalujemy komendą:
XADUnFile RAM:PyMUI-0.4.morphos-r238.lha SYS:
Po tej operacji mamy już w pełni przygotowaną platformę do pracy. Teraz powinniśmy mieć już działającą wersję PyMUI w systemie, co sprawdzimy w shellu Pythona wpisując:
python> from pymui import *
Jeżeli interpreter Pythona nie wyrzucił nam żadnego błędu, to znaczy, że wszystko mamy w porządku i możemy przejść do następnego kroku, którym jest oczywiście prosta aplikacja "Hello World". Nie zapomnijmy tutaj o użyciu edytora. Szkoda byłoby nie zachować efektów naszej pracy. Edycji możemy dokonać przy pomocy Eda z pakietu developer dla MorphOS-a. Ważne tylko by w konfiguracji zaznaczyć, żeby edytor zamieniał tabulatory na spacje. W innym wypadku dość często interpreter Pythona pokaże nam błędy składni.
Hello world
Będzie to przykład zupełnie prosty, zaczniemy od stworzenia okna z przyciskiem oraz notyfikacją, gdzie kliknięcie w obiekt „SimpleButton” spowoduje wyjście z programu. Teraz moduł PyMUI zaimportujemy samym poleceniem import. Taki sposób pozwoli nam na łatwe rozróżnienie metod i zaimportowanych pakietów. Przy pisaniu większych programów możemy się spotkać, że w dwóch pakietach występuje metoda o tej samej nazwie. Taki problem, możemy rozwiązać poprzez importowanie bez polecenia from lub zaimportowanie tylko określonych modułów z pakietu.
Ciekawym elementem kodu jest sekcja przypięcia notyfikacji, gdzie do wywołania funkcji używamy wyrażenia lambda. Wyrażenie to pozwala zdefiniować jednolinijkowe funkcje. Dzięki jej prostocie nie musimy używać ani nazwy funkcji, ani zwracać wyniku przez słowo kluczowe return. Lambda pozwala na oszczędzenie dużej ilości niepotrzebnego kodu. Zapamiętajmy - tam, gdzie funkcja jest trywialna i używamy jej w tym konkretnym miejscu kodu, używajmy wyrażenia lambda.
A więc do klawiatur.
#!python # Importujemy pakiet pymui import pymui # Tworzymy obiekt Aplikacji, okno i przycisk aplikacja = pymui.Application(Base='PyMUI_HelloWorld', Title='Hello World’, Description='Prosty przykład’) okno = pymui.Window('Hello, World!') przycisk = pymui.SimpleButton('Bye Bye!') # Przypisujemy okno do aplikacji i ustawiamy jako główny obiekt przycisk aplikacja.AddChild(okno) okno.RootObject = przycisk # ustawiamy notyfikację, która w momencie naciśnięcia przycisku bądź znaku x wychodzi z programu okno.Notify('CloseRequest’, lambda e: app.Quit(), when = True) przycisk.Notify('Pressed’, lambda a: app.Quit(), when = False) # Otwieramy okno i uruchamiamy aplikację okno.OpenWindow() aplikacja.Run() # Niekonieczne Python sam zwolni pamięć del aplikacja
Efektem powyższego kodu powinna być taka prosta aplikacja.
Nie za duży program
Stworzymy prosty czytnik RSS, pozwalający na odczytanie wiadomości z prawie każdej strony posiadającej tę funkcjonalność. Program będzie składał się z formularza z polem tekstowym, przyciskiem oraz listą pymui.List() i wyświetli wiadomości z podanej przez użytkownika strony. Zaczniemy go pisać od zaimportowania modułów xml.dom.minidom (pozwoli nam parsować dokument pobrany z sieci), urlib (pobierzemy plik ze strony www) oraz pymui (do wyświetlenia interfejsu graficznego). Sam kod aplikacji rozpoczniemy od stworzenia grupy obiektów wywołaniem klasy pymui.Group(), obiektów pymui.Text() pozwalających wyświetlać informacje tekstowe, a także dodamy do formularza pole wejściowe pymui.String() i prosty przycisk pymui.SimpleButton(). Po stworzeniu obiektów musimy wszystkie elementy dodać do grupy, co czynimy metodą AddChild(obiekt). Kolejne obiekty MUI dodadzą się do naszej grupy w kolejności ich wywołań. Do przycisku dodamy teraz notyfikację, która po kliknięciu w niego wywoła funkcję pobierzRss(), do której przekażemy wartość wprowadzoną w polu url_rss. Następnie dodamy funkcję, która parsuje nasz dokument, wyszukując nazwy i odnośniki do artykułu w pobranym dokumencie. Tak pobrane dane dodamy do obiektu lista i pozwolimy wyświetlić w aplikacji. A więc bierzmy się do pisania.
#-*- coding: utf-8 -*- import xml.dom.minidom, urllib, pymui #zaczynamy od utworzenia grupy, w której umieścimy wszystkie kontrolki MUI grupa = pymui.Group() #tworzymy kolejno pole tytułu aplikacji, pole wejściowe, przycisk, listę do przechowywania wiadomości oraz pole informacyjne tytul = pymui.Text(Contents = 'Lista artykułów’) url_rss = pymui.String() przycisk = pymui.SimpleButton('Kliknij') lista = pymui.List() info = pymui.Text() #wszystkie nowo utworzone obiekty dodajemy do grupy grupa.AddChild(tytul) grupa.AddChild(url_rss) grupa.AddChild(przycisk) grupa.AddChild(lista) grupa.AddChild(info) #tworzymy notyfikacje dla przycisku, po którego kliknięciu wywołujemy funkcję pobierzRss(), do której przekazujemy adres wpisanej przez nas strony przycisk.Notify('Pressed',lambda a: pobierzRss(url_rss.Contents), when = True) #z tekstu wiadomości usuwamy polskie znaki - kodowanie 'UTF-8' w tekście i Unikod Pythona jest nieco skomplikowany i powoduje problemy w połączeniu z PyMUI, #błąd ten zniknie wraz z dostosowaniem PyMUI do Pythona z serii 3.x def usunPlZnaki(text): x = {'\xc3\xb3': 'o', '\xc3\x93': 'O', '\xc4\x85': 'a', '\xc4\x84' : 'A', '\xc4\x99': 'e', '\xc4\x98': 'E', '\xc5\x82' : 'l', '\xc5\x81' :'L', '\xc4\x87' :'c', '\xc4\x86' :'C', '\xc5\x84' :'n', '\xc5\x83' :'N', '\xc5\xbc': 'z', '\xc5\xbb' : 'Z', '\xc5\xba' : 'z', '\xc5\xb9' : 'Z', '\xc5\x9b' : 's', '\xc5\x9a' : 'S', '\xC4\x85': '&'} for key, value in x.items(): text = text.replace(key, value) return text.encode('utf-8') #funkcja pobiera stronę z serwera i przekazuje do obiektu parsera xml, sprawdza czy wpisany link istnieje oraz, czy podany url zawiera składnię xml def pobierzRss(strona_rss): try: usock = urllib.urlopen(strona_rss.contents) dom = xml.dom.minidom.parse(usock) info.Contents = 'Wiadomosci z ' + strona_rss.contents parsujRSS(dom) except IOError: info.Contents = 'Nie mogę otworzyć Twojego odnośnika.' except xml.parsers.expat.ExpatError: info.Contents = 'Odnośnik, który podałeś, prawdopodobnie nie jest RSS-em.' #dwie funkcje pozwalające wyłuskać tekst z xml def pobierzTextPojedynczo(node): parts = [child.data for child in node.childNodes if child.nodeType == node.TEXT_NODE] return u"".join(parts) def pobierzText(nodelist): return u"".join(pobierzTextPojedynczo(node) for node in nodelist) #funkcja parsująca obiekt przekazany w funkcji pobierzRss(), podczas iteracji dodajemy kolejne elementy listy do obiektu pymui.List() def parsujRSS(dom): items = dom.getElementsByTagName("item") for i in items: title = i.getElementsByTagName("title") link = i.getElementsByTagName("link") wiadomosc = usunPlZnaki(pobierzText(title).encode('utf-8')) + u' link: ' + pobierzText(link).encode('utf-8') lista.InsertSingleString(wiadomosc) return lista #tworzymy okno aplikacji o rozmiarach 500px x 400px i dodajemy wcześniej utworzona grupę jako główny obiekt okno = pymui.Window(Width=500, Height=400, CloseOnReq=True, RootObject=grupa) #ustawiamy notyfikacje dla obiektu, pozwalając po kliknięciu w przycisk zamknąć aplikację okno.Notify('CloseRequest', lambda *a: aplikacja.Quit(), when = True) #dodajemy okno i je wyświetlamy aplikacja = pymui.Application(okno) okno.OpenWindow() #wreszcie uruchamiamy gotową aplikację aplikacja.Run()
Teraz wpisz w pole tekstowe adres strony RSS np: http://www.ppa.pl/newsy/b2rss.xml. Jeżeli dostałeś listę artykułów, to znaczy, że się udało. Gratulacje.
Jak uczyć się dalej?
Niestety muszę zasmucić maniaków czytania dokumentacji - autor pakietu PyMUI jeszcze jej nie napisał. Na stronie projektu znajdują się jedynie nieco przestarzałe materiały z poprzednich wersji beta. Ale nic straconego. Wystarczy zagłębić się w źródłach pakietu, gdzie znajdziemy uporządkowane funkcje z dość skąpym opisem. Ponadto Yomgui, autor, pisze przy wykorzystaniu PyMUI aplikację Griboullis – program graficzny. Źródła aplikacji możemy pobrać ze strony http://yellowblue.free.fr/yiki/doku.php/en:dev:gribouillis2:start później ją rozpakować i czytać. Ze swojej strony postaram się, w miarę wolnego czasu, napisać kolejny artykuł dotyczący PyMUI i tym uzupełnić braki w dokumentacji, a także jeszcze bardziej zachęcić do rozpoczęcia zabawy z Pythonem.
Odnośniki
Oficjalna strona pakietu PyMUI
Oficjalna strona MUI
Tutorial MUI Grzegorza Kraszewskiego
Artykuł oryginalnie pojawił się w szóstym numerze Polskiego Pisma Amigowego.