Blog (29)
Komentarze (476)
Recenzje (0)
@iluzionSamowystarczalne aplikacje Pythona

Samowystarczalne aplikacje Pythona

19.06.2011 | aktual.: 19.06.2011 17:53

Wstęp

Programy napisane w Pythonie mają rozszerzenie .py lub .pyw. Zazwyczaj rozszerzenie .py stosuje się dla aplikacji konsolowych, a .pyw dla aplikacji graficznych. Różnica między nimi polega na tym, że programy z rozszerzeniem .pyw nie uruchamiają w tle okna wiersza poleceń.

Zalety plików py

* programy/skrypty są niewielkie * można zobaczyć kod źródłowy programu przed jego uruchomieniem

Wady plików py

* do działania wymagają interpetera języka Python, a często dodatkowych bibliotek * nie zawsze chcemy dzielić się kodem źródłowym z innymi

Jeśli piszemy programy na własny użytek to powyższe wady nie mają znaczenia. Problem zaczyna się, gdy chcemy podzielić się programem z innymi. Nie każdy użytkownik Windowsa ma zainstalowany interpreter tego języka, nie wspominając już o wymaganych bibliotekach. Znacznie częściej możemy spotkać na komputerach środowisko uruchomieniowe JRE dla programów napisanych w języku Java. Nieco inaczej przedstawia się sytuacja wśród użytkowników Linuksa. Popularne dystrybucje zwykle zawierają Pythona, a część popularnych bibliotek jest instalowana wraz z zależnościami innych programów. Istnieją jednak rozwiązania powyższych problemów.

Rozwiązanie nr 1

Zachęcenie użytkowników naszego programu do zainstalowania Pythona oraz stosownych bibliotek. Nie wszyscy jednak mają na to ochotę, inni nie potrafią zainstalować tego co jest wymagane do działania programu (problem z wyborem odpowiedniej wersji, architektury itp.).

Rozwiązanie nr 2

Dostarczyć wraz z programem właściwe instalatory Pythona i bibliotek. W ten sposób również nakładamy na użytkownika pewne obowiązki.

Rozwiązanie nr 3

Skorzystać z rozszerzenia py2exe.

Zalety i wady py2exe

Łatwo się domyślić, sugerując się nazwą, czym jest py2exe. Rozszerzenie to umożliwa konwersję plików/skryptów Pythona do wykonywalnych programów exe.

Zalety py2exe

* łatwość tworzenia samodzielnych aplikacji * brak problemów związanych z instalacją właściwych wersji Pythona i bibliotek * brak konfliktów pomiędzy zainstalowaną w systemie wersją Pythona i bibliotek (jeśli takie posiadamy), a wersją wykorzystywaną przez program

Wady py2exe

* programy mają znaczne rozmiary (z tego względu, że dostarczany jest wraz z nimi interpreter oraz biblioteki)

Książka kucharska

Składniki

Aby zbudować napisaną w Pythonie aplikację dla systemu Windows będziemy potrzebować:

* Python 2.5.x, 2.6.x lub 2.7.x. * py2exe

Na potrzeby tego wpisu wymagany będzie również mój ulubiony zestaw:

* PyQt * NumPy * matplotlib

Przepis na aplikację exe

W celu zbudowania aplikacji exe należy umieścić w katalogu z programem/skryptem .py plik setup.py, a następnie uruchomić wiersz poleceń (cmd), przejść do katalogu i wydać polecenie:

python setup.py py2exe

lub (w przypadku gdy nie mamy dodanej właściwej ścieżki do zmiennej systemowej Path)

C:\Python27\python setup.py py2exe

uwzględniając właściwą ścieżkę do pliku python.exe.

W wyniku działania polecenia powstaną dwa katalogi: build oraz dist. Katalog dist zawiera właściwy program. Wystarczy go spakować i udostępnić lub skorzystać z aplikacji do tworzenia instalatorów.

Uwaga

W niektórych przypadkach powyższe polecenie kończy się komunikatem o braku biblioteki .dll. Istnieje duże prawdopodobieństwo, że masz gdzieś na dysku te pliki. Wystarczy je skopiować do katalogu z plikiem setup.py. Jeśli ich nie posiadasz, zapytaj Google. Pamiętaj jednak o bezpieczeństwie i zwracaj uwagę na to czy pobierane pliki można legalnie dystrybuować.

Hello World

Przejdźmy do klasycznego przykładu. Program ,,Hello world'' w Pythonie ma następującą postać:

print('Hello World!')

Powyższy fragment kodu zapisujemy w wybranej lokalizacji w pliku hello.py. Następnie w tym samym folderze umieszczamy plik setup.py o takiej zawartości:

from distutils.core import setup
import py2exe

setup(console=['hello.py'])

Komentarz jest chyba zbędny. Warto jedynie zaznaczyć, że console stosujemy dla aplikacji konsolowych (uruchamianych z poziomu wiersza poleceń). W przypadku programów graficznych w tym miejscu umieścić windows.

Uruchamiamy wiersz poleceń, przechodzimy do katalogu z plikami hello.py oraz setup.py i wydajemy polecenie

python setup.py py2exe

(screenshot 1)

W ten sposób utworzone zostały dwa katalogi: build oraz dist. Program o nazwie hello.exe (takiej jak nazwa skryptu py) znajduje się w folderze dist.

(screenshot 2)

Program: hello.zip (2.41 MB)

Poza plikiem exe w katalogu znajduje się kilka innych plików. Jest to właśnie jedna z wad tego rozwiązania opisana powyżej. Cały folder zajmuje na dysku 4.7 MB. Dużo jak na program wyświetlający jedynie Hello World! na ekranie. Dobra wiadomość jest taka, że rozbudowanie aplikacji konsolowej nie wpłynie znacząco na rozmiar katalogu dist. Chyba, że skorzystamy z dodatkowych bibliotek.

PyQt -- aplikacja graficzna

W drugim przykładzie zbudujemy aplikację graficzną korzystającą z biblioteki PyQt. W tym celu skorzystamy z gotowych przykładów dostarczanych wraz z biblioteką.

W katalogu C:\Python27\Lib\site-packages\PyQt4\examples znajduje się duża liczba przykładów w postaci plików .pyw (jako, że mamy do czynienia z aplikacjami graficznymi).

Wybieramy jeden z nich. Dla pozostałych procedura postępowania będzie analogiczna (o ile program nie korzysta z dodatkowych bibliotek, np. OpenGL).

Wybrałem program lighting.pyw. Czas na napisanie pliku setup.py.

from distutils.core import setup
import py2exe

setup(windows=[{"script" : "lighting.pyw"}], options={"py2exe" : {"includes" : ["sip", "PyQt4"]}})

Ten plik można wykorzystać do każdego programu korzystającego z PyQt, uwzględniając właściwą nazwę skryptu.

Korzystamy z polecenia

python setup.py py2exe

W rezultacie otrzymujemy komunikat:

*** finding dlls needed ***
error: MSVCP90.dll: No such file or directory

Jest to sytuacja opisana powyżej. Należy poszukać na dysku lub w internecie pliku MSVCP90.dll i skopiować go do katalogu z plikami lighting.pyw oraz setup.py.

Po skopiowaniu ponownie wydajemy powyższą komendę. Teraz już wszystko powinno pójść bez problemu.

387773

Program: lighting.zip (8.17 MB)

PyLab + PyQt

Można pójść o krok dalej. Na koniec zbudujemy aplikację korzystającą z bibliotek PyQt, NumPy oraz matplotlib (PyLab). Będzie to prosty program wyświetlający wykres funkcji sinus. Mimo, że PyQt nie jest potrzebne do tego celu, zostanie tu zastosowane w celu skomplikowania pliku setup.py. Poza tym PyQt dodaje do programu kilka ciekawych opcji i ładny natywny wygląd. Ale o tym później. Skupmy teraz uwagę na plikach źródłowych. Oto program, który nazwałem matpyqt.pyw

import matplotlib
matplotlib.use('Qt4Agg')

## Opcjonalnie można zmienić czcionkę.
from matplotlib import rcParams
rcParams['font.family'] = 'sans-serif'
rcParams['font.sans-serif'] = ['Verdana']

from pylab import * # nie zaleca się importować wszystkiego, ale czasami jest to wygodne

subplot(111, axisbg = '#e9e5cd')
t = arange(0.0, 2.0, 0.01)
s = sin(2 * pi * t)
plot(t, s, color = '#a66e25')
xlabel('time (s)')
ylabel('voltage (mV)')
title('Test matplotlib & PyQt4')
grid(True)
show()

oraz plik setup.py

from distutils.core import setup
import py2exe

import glob

opts = {
    'py2exe': {'includes' : ['sip', 'PyQt4', 'matplotlib.backends.backend_qt4agg', 'pylab'],
               'excludes' : ['_gtkagg', '_tkagg', '_agg2', '_cairo', '_cocoaagg', '_fltkagg', '_gtk', '_gtkcairo']
              }
       }

data_files = [(r'mpl-data', glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\*.*')),
              (r'mpl-data', [r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\matplotlibrc']),
              (r'mpl-data\images', glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\images\*.*')),
              (r'mpl-data\fonts', glob.glob(r'C:\Python27\Lib\site-packages\matplotlib\mpl-data\fonts\*.*'))]

setup(windows=[{'script' : 'matpyqt.pyw'}], options=opts, data_files = data_files)

Przyda nam się również plik msvcp90.dll. Skopiujmy go zatem do katalogu i wykonajmy kolejny raz

python setup.py py2exe

Po uruchomieniu widzimy jednak, że coś jest nie tak. Brakuje ikon. Jest to błąd, który mam nadzieję zostanie w przyszłości naprawiony. Ikony zostały skopiowane do folderu dist\mpl-data\images ale nie są wyświetlane. Istnieje pewna sztuczka, która pozwala rozwiązać ten problem -- należy zmienić rozszerzenia plików png w katalogu dist\mpl-data\images na svg.

387783

Poprawnie działający program: matpyqt.zip (17.4 MB)

Rozmiar programu budzi podejrzenia, ale należy mieć na uwadze, że katalog dist zawiera kompletne biblioteki PyQt, NumPy oraz matplotlib, a wykorzystujemy jedynie niewielki promil ich możliwości.

Ponadto matplotlib zapewnia nam możliwość zapisu plików w wielu popularnych formatach, a PyQt oprócz ładnego wyglądu aplikacji dodaje kilka przydatnych opcji.

(screenshot 1)(screenshot 2)(screenshot 3)

Jakość ma znaczenie

Wykresy matplotlib wróżniają się wysoką jakością. Zapisać je można w formatach: eps, ps, pdf, png, raw, rgba, svg, svgz.

Pliki eps, ps, pdf można łatwo osadzić w dokumentach LaTeX-a lub wydrukować w dowolnej skali bez straty jakości. Pliki svg mogą być wykorzystywane na stronach internetowych. Współczesne przeglądarki radzą sobie z ich wyświetlaniem. Grafiki svg można często spotkać m.in. na Wikipedii. Ich zaletą jest to, że można je powiększać bez straty jakości.

Z plików svg korzysta domyślnie program do grafiki wektorowej Inkscape. Nic nie stoi na przeszkodzie, aby wykres z matplotlib otworzyć w Inkscape.

387792

Jako ciekawostkę można dodać, że Inkscape również zawiera w swoim katalogu interpreter Pythona oraz kilka bibliotek, m.in. NumPy oraz PIL.

Aktualizacja: cx_Freeze

W komentarzu pod wpisem TestamenT zasugerował rozwiązanie alternatywne w postaci cx_Freeze. Oto krótka analiza tego modułu.

Hello world -- aplikacje konsolowe

W celu przeprowadzenia konwersji skryptu hello.py do pliku exe wystarczy wydać polecenie:

C:\Python27\Scripts\cxfreeze hello.py

Można także skorzystać z jednej z dostępnych opcji, np. wybrać katalog, w którym zostanie utworzona aplikacja.

cxfreeze hello.py --target-dir dist

Skrypt setup.py jest w tym przypadku zbędny.

PyQt -- aplikacje graficzne

W przypadku aplikacji korzystających z PyQt postępujemy podobnie jak powyżej, ale dodajemy opcję --base-name=Win32GUI. Dzięki tej opcji przy uruchamianiu aplikacji nie będzie pojawiało się okno wiersza poleceń.

C:\Python27\Scripts\cxfreeze nazwa_programu.pyw --base-name=Win32GUI

Skrypt setup.py również w tym wypadku nie jest konieczny. Dla przykładu nr 3, czyli programu korzystającego dodatkowo z biblioteki matplotlib, prawdopodobnie konieczne będzie dodatnie pliku setup.py.

Wnioski dotyczące cx_Freeze

Python 3 -- 32 & 64‑bit!

Pierwszą rzeczą, która rzuca się w oczy na stronie projektu to wsparcie dla wszystkich popularnych wersji Pythona, łącznie z najnowszą wersją 3.2.

Obsługa systemów Windows i Linux

Narzędzia takie jak py2exe (Windows) czy py2app (Mac OS X) przeznaczone są tylko dla jednego systemu, natomiast cx_Freeze pozwala również na budowanie samodzielnych aplikacji dla dystrybucji Linuksa.

Łatwość budowania aplikacji

Wygląda na to, że konwersja do plików exe jest jeszcze łatwiejsza niż w przypadku py2exe. W przypadku prostych aplikacji konsolowych oraz graficznych opartych na PyQt nie ma potrzeby dodawania plików setup.py

Czytelniejsze komentarze

Podczas budowania aplikacji py2exe oraz cx_Freeze wyświetla komentarze o przebiegu tego procesu. Komentarze wyświetlane przez cx_Freeze wydają się być bardziej czytelne.

py2exe vs cx_Freeze

Mniejsza liczba plików w katalogu dist

cx_Freeze produkuje mniejszą liczbę plików niż py2exe (chociaż nie wpływa to znacząco na rozmiar aplikacji)

py2exe vs cx_Freeze

Wybrane dla Ciebie
Komentarze (7)