<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
><channel><title>FLLOG &#187; python</title> <atom:link href="http://www.michalklich.com/tag/python/feed/" rel="self" type="application/rss+xml" /><link>http://www.michalklich.com</link> <description>Fedora Linux Blog</description> <lastBuildDate>Wed, 01 Jun 2011 18:44:40 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.0.4</generator> <item><title>Py4A czyli piszemy aplikację na androida.</title><link>http://www.michalklich.com/2011/06/01/py4a-czyli-piszemy-aplikacje-na-androida/</link> <comments>http://www.michalklich.com/2011/06/01/py4a-czyli-piszemy-aplikacje-na-androida/#comments</comments> <pubDate>Wed, 01 Jun 2011 18:40:17 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[android]]></category> <category><![CDATA[python]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=1075</guid> <description><![CDATA[Jak obiecałem jest to krótki opis w jaki sposób zmajstrować aplikację z prostym GUI napisaną w pythonie na androida. Py4A ma wiele funkcji ale niestety brakuje mu dostępu do podstawowych funkcji do tworzenia interfejsów dla androida. Konieczne jest posiłkowanie się WebView czyli htmlem oraz javascriptem. Jeśli nadal jesteś chętny to czytaj dalej. Muszę zaznaczyć na [...]<p><a
href="http://www.michalklich.com/2011/06/01/py4a-czyli-piszemy-aplikacje-na-androida/">Py4A czyli piszemy aplikację na androida.</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Jak obiecałem jest to krótki opis w jaki sposób zmajstrować aplikację z prostym GUI napisaną w pythonie na androida. Py4A ma wiele funkcji ale niestety brakuje mu dostępu do podstawowych funkcji do tworzenia interfejsów dla androida. Konieczne jest posiłkowanie się WebView czyli htmlem oraz javascriptem. Jeśli nadal jesteś chętny to czytaj dalej.<br
/> <span
id="more-1075"></span><br
/> Muszę zaznaczyć na samym początku artykułu, że kod nie jest doskonały a sam przykład nie jest może do końca przemyślany. Należy to traktować jako wstęp do swoich aplikacji i drogowskaz. Jeśli ktoś ma uwagi odnośnie kodu to proszę bardzo jednak dużo bardziej jestem zainteresowany innymi sposobami użycia pythona na androidzie. Kod sam w sobie nie wykonuje żadnych skomplikowanych operacji na sprzęcie, pomimo że API to umożliwia, jak już pisałem przykład nie jest do końca przemyślany a moim celem było tylko pokazanie, że aplikacje mogą posiadać interfejs a nie być po prostu skryptami. Koniec biadolenia, przechodzimy do mięska.<br
/> Najskromniejsza z aplikacji to tak naprawdę dwa pliki. Py który zawiera kod, mechanikę, funkcje itd. oraz html czyli interfejs. Python zaakceptuje wszystko pod warunkiem oczywiście, że są odpowiednie moduły. Html natomiast przyjmie js oraz css więc daje duże możliwości.<br
/> Oto plik .py, opiszę poszczególne fragmenty.</p><pre class="brush: python; title: ; notranslate">
import android

droid = android.Android()
droid.webViewShow('file:///sdcard/sl4a/scripts/gasoline_ui.html')
while True:
    dist = droid.eventWaitFor('dist').result['data']
    gas = droid.eventWaitFor('gas').result['data']
    res = float(gas) / float(dist) * 100
    droid.dialogCreateAlert('Wynik kalkulacji', 'Spalanie: %s' % res)
    droid.dialogSetNeutralButtonText(&quot;Ok&quot;)
    droid.dialogShow()
    result = droid.dialogGetResponse().result
    droid.dialogDismiss()
</pre><p>Początek jest na tyle prosty, że nie ma co pisać. W pętli dzieje się cała mechanika, python czeka w niej na zdarzenia uruchamiane przez użytkownika w wymienionym wcześniej pliku html (o nim później). Wartości przypisywane są do odpowiednich zmiennych a potem wynik jest wypluwany w formie okna dialogowego. Żadnych trudności, wszystko proste i przyjemne.<br
/> A teraz plik html.</p><pre class="brush: xml; title: ; notranslate">
&lt;html&gt;
  &lt;head&gt;
    &lt;link type=&quot;text/css&quot; rel=&quot;stylesheet&quot; href=&quot;/test.css&quot;&gt;
    &lt;title&gt;Kalkulator spalania&lt;/title&gt;
    &lt;script&gt;
      var droid = new Android();

      var calc = function() {
      var dist = document.getElementById('dist').value;
      var gas = document.getElementById('gas').value;
      droid.eventPost(&quot;dist&quot;, dist);
      droid.eventPost(&quot;gas&quot;, gas);
      };
    &lt;/script&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;form onsubmit=&quot;calc(); return false;&quot;&gt;
      &lt;label for=&quot;dist&quot;&gt;Ile przejechałeś?&lt;/label&gt;
      &lt;input type=&quot;text&quot; id=&quot;dist&quot; /&gt;
      &lt;br /&gt;
      &lt;label for=&quot;gas&quot;&gt;Ile zatankowałeś?&lt;/label&gt;
      &lt;input type=&quot;text&quot; id=&quot;gas&quot; /&gt;
      &lt;input type=&quot;submit&quot; value=&quot;Calc&quot; /&gt;
    &lt;/form&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre><p>Najważniejszą częścią tego pliku jest javascript, który również tworzy obiekt API i poprzez jego metody komunikuje się z pythonem, odpowiedzialna jest za to funkcja eventPost(). Nie jest to zbyt skomplkowane. Jak już ma oba pliki to najlepiej je popchnąć na urządzenie używając adb (rozważam opisanie instalacji i konfiguracji w osobnym poście) poleceniem</p><pre class="brush: bash; title: ; notranslate">
adb push plik.py /sdcard/sl4a/scripts/
adb push plik.html /sdcard/sl4a/scripts/
</pre><p>Po tej operacji SL4A umożliwi odpalenie programu z listy skryptów.<br
/> <a
href="http://www.michalklich.com/wp-content/uploads/2011/05/screenshot_12.png"><img
src="http://www.michalklich.com/wp-content/uploads/2011/05/screenshot_12.png" alt="" title="Główny ekran" width="320" height="480" class="aligncenter size-full wp-image-1092" /></a><br
/> <a
href="http://www.michalklich.com/wp-content/uploads/2011/05/screenshot_10.png"><img
src="http://www.michalklich.com/wp-content/uploads/2011/05/screenshot_10.png" alt="" title="Wynik kalkulacji" width="320" height="480" class="aligncenter size-full wp-image-1089" border="1" /></a><br
/> Nie jest to piękne rozwiązanie ale umożliwia to zabawę pythonem, do czasu aż API nie będzie wspierać natywnych okienek lub nie pojawi się PyQT lub PyGTK trzeba będzie tak pisać lub przerzucić się na javę.</p><p><a
href="http://www.michalklich.com/2011/06/01/py4a-czyli-piszemy-aplikacje-na-androida/">Py4A czyli piszemy aplikację na androida.</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2011/06/01/py4a-czyli-piszemy-aplikacje-na-androida/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Py4A &#8211; Python w Androidzie</title><link>http://www.michalklich.com/2011/05/25/py4a-python-w-androidzie/</link> <comments>http://www.michalklich.com/2011/05/25/py4a-python-w-androidzie/#comments</comments> <pubDate>Wed, 25 May 2011 19:04:28 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[android]]></category> <category><![CDATA[programowanie]]></category> <category><![CDATA[python]]></category> <category><![CDATA[py4a]]></category> <category><![CDATA[sl4a]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=1061</guid> <description><![CDATA[A więc kupiłeś telefon z androidem. Pierwsze dni byłeś ostrożny, tylko instalacja aplikacji i ustawianie telefonu. A potem rootujesz telefon i pierwsze mody. Po paru modach zaczyna się robić nudno trochę bo ile można brać a nic nie dawać w zamian. Znasz pythona i postanawiasz stworzyć coś swojego na telefon. I w tym miejscu przydaje [...]<p><a
href="http://www.michalklich.com/2011/05/25/py4a-python-w-androidzie/">Py4A &#8211; Python w Androidzie</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>A więc kupiłeś telefon z androidem. Pierwsze dni byłeś ostrożny, tylko instalacja aplikacji i ustawianie telefonu. A potem rootujesz telefon i pierwsze mody. Po paru modach zaczyna się robić nudno trochę bo ile można brać a nic nie dawać w zamian. Znasz pythona i postanawiasz stworzyć coś swojego na telefon. I w tym miejscu przydaje się ten krótki artykuł.<br
/> <span
id="more-1061"></span><br
/> Opiszę tutaj w jaki sposób zainstalować niezbędne programy na telefonie aby można było pisać aplikacje w pythonie. Sprawa jest banalnie prosta. Jedyne co potrzeba to telefon z androidem oraz dostęp do internetu na telefonie (najlepiej poprzez wifi, chyba że masz duże limity u operatora komórkowego) lub komputerze. Wygodniej jest użyć telefonu do pobrania aplikacji, oszczędzisz sobie kopiowania plików poprzez kabel lub bluetooth. Ok, masz wszystko? Zaczynamy.<br
/> <strong>Zanim zaczniesz instalować soft przejdź do ustawień w telefonie, do części odpowiedzialnej za aplikacje i włącz instalację programów z nieznanych źródeł.</strong><br
/> Pierwsze co jest potrzebne to SL4A (Scripting Layer for Android) czyli program który umożliwi odpalanie programów napisanych w pythonie (i nie tylko. Perl, JRuby, Lua, BeanShell, JavaScript, Tcl, oraz shelle. Autorzy planują dodać inne języki.). Otwórz <a
href="http://code.google.com/p/android-scripting/">http://code.google.com/p/android-scripting/</a> w telefonie i kliknij w w kod QR, jest duży i łatwiejszy do trafienia niż linki po lewej stronie. Plik który instalujesz to <em>sl4a_r4.apk</em>. Po instalacji w menu pojawi się SL4A ale po uruchomieniu jest pusty.<br
/> Następny krok to instalacja pythona czyli Py4A (Python for Android). Są dwie możliwości: instalacja ze strony SL4A lub ze strony Py4A gdzie umieszczona jest nowsza wersja. Jeśli wybrałeś pierwszą opcję to po lewej stronie w menu Downloads kliknij na <em>PythonForAndroid_r4.apk</em> i zainstaluj. W drugim wypadku przejdź na <a
href="http://code.google.com/p/python-for-android/">http://code.google.com/p/python-for-android/</a> i analogicznie w sekcji Downloads kliknij na <em>PythonForAndroid_r5.apk</em>.<br
/> Następny krok jest taki sam, niezależnie od wybranej wersji. W menu telefonu znajdź i odpal Python For Android, z pewnością poznasz ikonkę. Na ekranie zobaczysz wersje pythona oraz dodatków które masz zainstalowane. W tej chwili nie powinieneś mieć żadnych numerów więc trzeba wcisnąć Install i poczekać aż aplikacja pobierze i rozpakuje wszystko. Po tej operacji w SL4A w menu Scripts będą widoczne przykładowe skrypty pythonowe. Polecam odpalić parę, klikając na wybranym i wybierając ikonę terminala a następnie obejrzeć kod wybierając ikonę ołówka.<br
/> To wszystko, w następnych artykułach postaram opisać jak napisać aplikację a także jak zbudować paczkę apk. Dla niecierpliwych parę stron lektury: <a
href="http://code.google.com/p/android-scripting/wiki/AndroidFacadeAPI">opis API</a> oraz <a
href="http://code.google.com/p/android-scripting/wiki/ApiReference">lista metod API</a>.</p><p><a
href="http://www.michalklich.com/2011/05/25/py4a-python-w-androidzie/">Py4A &#8211; Python w Androidzie</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2011/05/25/py4a-python-w-androidzie/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Przedszkole w edytorze</title><link>http://www.michalklich.com/2011/05/02/przedszkole-w-edytorze/</link> <comments>http://www.michalklich.com/2011/05/02/przedszkole-w-edytorze/#comments</comments> <pubDate>Mon, 02 May 2011 09:16:39 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[programowanie]]></category> <category><![CDATA[python]]></category> <category><![CDATA[formatowanie]]></category> <category><![CDATA[pep8]]></category> <category><![CDATA[pylint]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=1030</guid> <description><![CDATA[Formatowanie kodu jest ważne. To jest fakt. Ostatnio zetknąłem się z ciekawymi próbami sprawienia aby kod był bardziej czytelny, niestety nie udało mi się opisać tego przed moim znajomym. Polecam lekturę pod którą podpisuję się obiema rękami. Ze swojej strony pragnę dodać tylko bardzo &#8222;ciekawy&#8221; sposób definiowania zmiennych albo słowników. Za pewne można użyć go [...]<p><a
href="http://www.michalklich.com/2011/05/02/przedszkole-w-edytorze/">Przedszkole w edytorze</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Formatowanie kodu jest ważne. To jest fakt. Ostatnio zetknąłem się z ciekawymi próbami sprawienia aby kod był bardziej czytelny, niestety nie udało mi się opisać tego przed <a
href="http://rdobosz.blogspot.com/2011/04/dlaczego-ludzie-formatuja-kod.html">moim znajomym</a>. Polecam lekturę pod którą podpisuję się obiema rękami. Ze swojej strony pragnę dodać tylko bardzo &#8222;ciekawy&#8221; sposób definiowania zmiennych albo słowników. Za pewne można użyć go w innych przypadkach ale nie mam zamiaru marnować czasu na wymyślanie takich bzdur.<br
/> <span
id="more-1030"></span><br
/> Jeśli piszesz w taki sposób to robisz to źle.</p><pre class="brush: python; title: ; notranslate">
pierwsza_zmienna_od_długiej_nazwie                = 1
druga                                             = 2
trzecia_zmienna                                   = 3
czwarta_zmienna_o_długiej_nazwie_i_jeszcze_trochę = 4
</pre><p>Piękne, prawda? Ostatnią dodałem specjalnie najdłuższą aby pokazać bzdurność takiej konstrukcji. Po jej dodaniu musiałem przesunąć inne znaki przypisania w zmiennych wpisanych wcześniej!! Cóż za prostota rozwiązania.</p><pre class="brush: python; title: ; notranslate">
dict = {
'pierwsza'                                          : 1,
'druga'                                             : 2,
'trzecia_zmienna'                                   : 3,
'czwarta_zmienna_o_długiej_nazwie_i_jeszcze_trochę' : 4
}
</pre><p>Kolejny cudowny przykład.<br
/> Uważam to za błąd w każdym języku ponieważ to zaciemnia tylko kod i wymusza liczenie spacji a potem przerabianie całej konstrukcji w wypadku gdy dodaje się zmienną o dłuższej nazwie. Taka metoda musi być popularna wśród szachistów gdzie ruchy należy planować odpowiednio przed.<br
/> Proszę nie piszcie tak. Szachiści również.</p><p><a
href="http://www.michalklich.com/2011/05/02/przedszkole-w-edytorze/">Przedszkole w edytorze</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2011/05/02/przedszkole-w-edytorze/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>devs y u no pep8 in Emacs</title><link>http://www.michalklich.com/2011/02/16/devs-y-u-no-pep8-in-emacs/</link> <comments>http://www.michalklich.com/2011/02/16/devs-y-u-no-pep8-in-emacs/#comments</comments> <pubDate>Wed, 16 Feb 2011 20:19:15 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[emacs]]></category> <category><![CDATA[programowanie]]></category> <category><![CDATA[python]]></category> <category><![CDATA[pep8]]></category> <category><![CDATA[pyflakes]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=1004</guid> <description><![CDATA[Tytuł dosyć niezrozumiały ale w luźnym tłumaczeniu jest to pytanie &#8222;dlaczego nie używasz pep8 w Emacsie?&#8221;. Czym jest pep8? Jest to lista zaleceń odnośnie stylu kodowania. Tak, zgadza się, są to zalecenia więc nie są przymusowe ale na tyle logiczne oraz przemyślane, że warto je stosować. W końcu standaryzacja to nie jest nic złego jeśli [...]<p><a
href="http://www.michalklich.com/2011/02/16/devs-y-u-no-pep8-in-emacs/">devs y u no pep8 in Emacs</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Tytuł dosyć niezrozumiały ale w luźnym tłumaczeniu jest to pytanie &#8222;dlaczego nie używasz pep8 w Emacsie?&#8221;. Czym jest pep8? Jest to <a
href="http://www.python.org/dev/peps/pep-0008/">lista zaleceń</a> odnośnie stylu kodowania. Tak, zgadza się, są to zalecenia więc nie są przymusowe ale na tyle logiczne oraz przemyślane, że warto je stosować. W końcu standaryzacja to nie jest nic złego jeśli jest stosowana z umiarem oraz w odpowiednim miejscu. Jeśli interesuje Cię implementacja sprawdzania składni pod kątem pep8 w locie w Emacsie to czytaj dalej.<span
id="more-1004"></span><br
/> Wpis ten nie powstałby gdybym nie zmobilizował się lub nie został zmobilizowany do ustawienia sobie emacsa pod pep8. Aby ułatwić innym (oraz sobie bo mam tendencję do zapominania, potem sięgam do swojego bloga i voila) opiszę co trzeba zrobić aby cieszyć się pięknym kodem. Dla ludzi którzy wolą jednak nabywać wiedzę w tradycyjny sposób i reguły stosować klasycznie polecam <a
href="wwd.ca/stuff/pep8_cheat.pdf">ściągawkę</a> do wydrukowania. Przejdę do rzeczy. Potrzebujesz Emacsa a do niego pep8, pyflakes oraz flymake-cursor (to modyfikacja aby informacja o błędzie pojawiała się w minibuforze). Narzędzia pep8 oraz pyflakes łatwo zainstalować przy użyciu pipy.</p><pre class="brush: bash; title: ; notranslate">pip install pep8 pyflakes</pre><p>Natomiast <a
href="http://richardriley.net/projects/emacs/dotprogramming#sec-1.5.4">flymake-cursor</a> już trzeba ręcznie skopiować i zapisać jako flymake-cursor.el na ścieżce z plikami el. Ja zapisałem w /usr/share/emacs/site-lisp. Kolejny krok to modyfikacja pliku konfiguracyjnego .emacs. Należy dokleić do niego poniższy kod.</p><pre class="brush: plain; title: ; notranslate">(add-hook 'find-file-hook 'flymake-find-file-hook)
(when (load &quot;flymake&quot; t)
  (defun flymake-pyflakes-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
               'flymake-create-temp-inplace))
       (local-file (file-relative-name
            temp-file
            (file-name-directory buffer-file-name))))
      (list &quot;pycheckers&quot;  (list local-file))))
   (add-to-list 'flymake-allowed-file-name-masks
             '(&quot;\\.py\\'&quot; flymake-pyflakes-init)))
(load-library &quot;flymake-cursor&quot;)
(global-set-key [f10] 'flymake-goto-prev-error)
(global-set-key [f11] 'flymake-goto-next-error)</pre><p>Ostatni krok to stworzyć plik o nazwie pycheckers gdzieś w PATH oraz ustawić go jako wykonywalny. W tym miejscu można skonfigurować sobie pep8, przydatne gdy wcięcia kodu nie są wielokrotnością 4.</p><pre class="brush: bash; title: ; notranslate">#!/bin/bash

pyflakes &quot;$1&quot;
pep8 --ignore=E221,E701,E202 --repeat &quot;$1&quot;
true</pre><p>Tyle wystarczy, pozostaje restart Emacsa lub M-x eval-buffer w otwartym buforze z plikiem .emacs i już można korzystać.<br
/> Całość to właściwie opis ze strony <a
href="http://www.saltycrane.com/blog/2010/05/my-emacs-python-environment/">http://www.saltycrane.com/blog/2010/05/my-emacs-python-environment/</a> i polecam zajrzeć do źródła gdzie można znaleźć parę innych smaczków do emacsa.</p><p><a
href="http://www.michalklich.com/2011/02/16/devs-y-u-no-pep8-in-emacs/">devs y u no pep8 in Emacs</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2011/02/16/devs-y-u-no-pep8-in-emacs/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>django: unittest</title><link>http://www.michalklich.com/2010/08/24/django-unittest/</link> <comments>http://www.michalklich.com/2010/08/24/django-unittest/#comments</comments> <pubDate>Tue, 24 Aug 2010 08:50:25 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[programowanie]]></category> <category><![CDATA[django]]></category> <category><![CDATA[python]]></category> <category><![CDATA[unittest]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=873</guid> <description><![CDATA[Django jest pisane w pythonie, python jak każdy porządny język obsługuje testy jednostkowe. A więc Django również. Dzisiaj przedstawię po krótce jak wygląda sprawa z testami w Django. Rozprawkę oprę o unittesty z tego prostego powodu, że podobają mi się bardziej niż doctesty. Nie znaczy to, że są lepsze po prostu służą do testowania innych [...]<p><a
href="http://www.michalklich.com/2010/08/24/django-unittest/">django: unittest</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Django jest pisane w pythonie, python jak każdy porządny język obsługuje testy jednostkowe. A więc Django również. Dzisiaj przedstawię po krótce jak wygląda sprawa z testami w Django. Rozprawkę oprę o unittesty z tego prostego powodu, że podobają mi się bardziej niż doctesty. Nie znaczy to, że są lepsze po prostu służą do testowania innych przypadków, nie są pythonic ale ładnie obiektowe i ja je wolę po prostu.<br
/> <span
id="more-873"></span><br
/> Załóżmy, że masz model reprezentujący wyniki rzutów kostką do gry, do modelu jest dodana metoda sprawdzająca czy wynik jest parzysty czy nie.</p><pre class="brush: python; title: ; notranslate">
from django.db import models

class Kostka(models.Model):
    wynik = models.IntegerField()
    osoba = models.CharField(max_length = 10, default = 'Anonim')

    def _sprawdz_liczbe(self):
        if (wynik % 2):
            return 'Parzysta'
        else:
            return 'Nieparzysta'

    test_wyniku = property(_sprawdz_liczbe)
</pre><p>Na tym modelu chcemy wykonać następujące testy:</p><ul><li>Tworzenie obiektu (pole &#8216;wynik&#8217; nie posiada wartości domyślnych)</li><li>Tworzenie obiektu z wartością domyślną</li><li>Test parzystości wyniku</li></ul><p>Wszystkie testy dobrze trzymać w osobnym pliku, który nota bene jest tworzony wraz z projektem, plik <em>tests.py</em> znajduje się w katalogu aplikacji. Jest to wygodne i pozwala w łatwy sposób odnaleźć wszystkie testy w danej aplikacji. Zaczynamy od importów oraz stworzenia klasy testu.</p><pre class="brush: python; title: ; notranslate">
import unittest
from aplikacja.app.models import Kostka

class KostkaTestCase(unittest.TestCase):
</pre><p>Następnym krokiem jest przeładowanie metody <em>setUp()</em> w celu stworzenia zmiennych lub obiektów odpowiadających naszym wymaganiom. Jak w pythonie i tutaj możliwe jest przeładowanie metod <em>tearDown()</em>, <em>runTest()</em> i <em>suite()</em> ale nie jest to konieczne. W opisywanym przypadku tworzone są trzy właściwości które posłużą później do tworzenia obiektów; rzutu parzystego, nieparzystego, zwykłego rzutu oraz anonimowego rzutu testującego wartość domyślną.</p><pre class="brush: python; title: ; notranslate">
class KostkaTestCase(unittest.TestCase):
    def setUp(self):
        self.osoba = 'Michal'
        self.liczba_parzysta = 4
        self.liczba_nieparzysta = 5
</pre><p>Teraz czas na przygotowanie testów. Na pierwszy ogień idzie test tworzenia obiektu z podanymi obiema wartościami: <em>osoba</em> i <em>wynik</em>. Test powinien przejść bez żadnych problemów.</p><pre class="brush: python; title: ; notranslate">
class KostkaTestCase(unittest.TestCase):
...
    def test_tworzenie_obiektu(self):
        rzut = Kostka.objects.create(self.liczba_parzysta, self.osoba)
        self.assertTrue(rzut)
        self.assertEqual(rzut.wynik, 4)
        self.assertEqual(rzut.osoba, 'Michal')
</pre><p>Następny test to sprawdzenie czy pole osoba przyjmuje wartość domyślną.</p><pre class="brush: python; title: ; notranslate">
class KostkaTestCase(unittest.TestCase):
...
    def test_wartosci_domyslnej(self):
        rzut_anonim = Kostka.objects.create(self.liczba_parzysta)
        self.assertTrue(rzut_anonim)
        self.assertEqual(rzut_anonim.osoba, 'Anonim')
</pre><p>Kolejny test i ostatni, którego kod zaprezentuję to test parzystości. Drugi test jest analogiczny i nie widzę potrzeby umieszczania kodu. W tym przypadku nie testujemy czy obiekt został stworzony ponieważ jest to w poprzednich testach.</p><pre class="brush: python; title: ; notranslate">
class KostkaTestCase(unittest.TestCase):
...
    def test_parzystosci(self):
        rzut_parzysty = Kostka.objects.create(self.liczba_parzysta)
        self.assertEqual(rzut_parzysty.test_wyniku, 'Parzysty')
</pre><p>To wszystkie potrzebne testy, w tym momencie można je uruchomić i sprawdzić czy nasze testy lub model są poprawne. Do wykonania tego służy znany wszystkim <em>manage.py</em>.</p><pre class="brush: bash; title: ; notranslate">
./manage.py test app
</pre><p>Jeśli wszystko pójdzie dobrze to powinien ukazać się następujący listing, jeśli nie to opis błędu jest na tyle jasny (czasem stworzony przez nas), że szybko można poprawić test lub model.</p><pre class="brush: bash; title: ; notranslate">
----------------------------------------------------------------------
Ran 4 tests in 0.009s

OK
Destroying test database 'default'...
</pre><p>Jak widać jest to łatwe i przyjemne oraz w pełni zgodne z Pythonem. Koniec, wszystkim życzę 100% skuteczności wykonywanych testów.</p><p><a
href="http://www.michalklich.com/2010/08/24/django-unittest/">django: unittest</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2010/08/24/django-unittest/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Dajax i jquery 1.4.2</title><link>http://www.michalklich.com/2010/07/05/dajax-i-jquery-1-4-2/</link> <comments>http://www.michalklich.com/2010/07/05/dajax-i-jquery-1-4-2/#comments</comments> <pubDate>Mon, 05 Jul 2010 21:28:11 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[fedora]]></category> <category><![CDATA[programowanie]]></category> <category><![CDATA[dajax]]></category> <category><![CDATA[django]]></category> <category><![CDATA[javascript]]></category> <category><![CDATA[jquery]]></category> <category><![CDATA[python]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=751</guid> <description><![CDATA[Siedzę nad dużą aktualizacją mojego amatorskiego projektu www.gdziebylkaziu.pl i zaplanowałem sobie dorzucić trochę ajaxa do map google. Szperając po internecie znalazłem http://dajaxproject.com i zakochałem się, dzięki temu mogę wszystkie proste funkcjonalności ajax napisać w &#8230; pythonie! Cieszę się ponieważ pomimo tego, że javascript jest ok to wolę pythona, oj wolę. Przechodzimy do rzeczy. Ostrzegam rozwiązanie [...]<p><a
href="http://www.michalklich.com/2010/07/05/dajax-i-jquery-1-4-2/">Dajax i jquery 1.4.2</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Siedzę nad dużą aktualizacją mojego amatorskiego projektu <a
href="http://www.gdziebylkaziu.pl" target="_self">www.gdziebylkaziu.pl</a> i zaplanowałem sobie dorzucić trochę ajaxa do map google. Szperając po internecie znalazłem <a
href="http://dajaxproject.com/">http://dajaxproject.com</a> i zakochałem się, dzięki temu mogę wszystkie proste funkcjonalności ajax napisać w &#8230; pythonie! <img
src='http://www.michalklich.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> Cieszę się ponieważ pomimo tego, że javascript jest ok to wolę pythona, oj wolę. Przechodzimy do rzeczy. Ostrzegam rozwiązanie jest banalne i pewnie wiele osób na to wpadło.<span
id="more-751"></span>Na stronie <a
href="http://wiki.github.com/jorgebastida/django-dajax/" target="_self">dajaxproject</a> jak byk stoi, że wspierane są biblioteki jQuery 1.3.2 ale ja jestem niedowiarkiem, po prostu uważałem, że zmiany w stosunku do wersji 1.4.2 nie są aż tak duże. No ale się pomyliłem bo nie chciało działać. Funkcje jQuery <em>addClass()</em> lub <em>removeClass()</em> były wykonywane ale z parametrem którego nie akceptowały (zbadałem i wersja 1.3.2 nie ma takiego problemu). Rozwiązanie było proste jak drut a mianowicie skonwertować obiekty do łańcucha znaków czyli <em>toString()</em>. A teraz gdzie to zmieniamy, kod znajduje się w pliku <em>jquery.dajax.core.js</em>. Szukamy linijek</p><pre class="brush: jscript; title: ; notranslate">case 'addcc':
case 'remcc':
</pre><p>I do wywołań funkcji <em>addClass()</em> oraz <em>removeClass()</em> dodajemy <em>toString()</em></p><pre class="brush: jscript; title: ; notranslate">
case 'addcc':
jQuery.each(elem.val,function(){
$(elem.id).addClass(this.toString());
});
break;

case 'remcc':
jQuery.each(elem.val,function(){
$(elem.id).removeClass(this.toString());
});
break;
</pre><p>Prawda, że banalne. Następnie opiszę w jaki sposób używać dajax, jest to równie proste jak ten fix.</p><p><a
href="http://www.michalklich.com/2010/07/05/dajax-i-jquery-1-4-2/">Dajax i jquery 1.4.2</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2010/07/05/dajax-i-jquery-1-4-2/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Django i ajax</title><link>http://www.michalklich.com/2010/04/23/django-i-ajax/</link> <comments>http://www.michalklich.com/2010/04/23/django-i-ajax/#comments</comments> <pubDate>Fri, 23 Apr 2010 12:29:19 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[programowanie]]></category> <category><![CDATA[ajax]]></category> <category><![CDATA[django]]></category> <category><![CDATA[jquery]]></category> <category><![CDATA[python]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=709</guid> <description><![CDATA[W mojej nowej pracy, pracuję tam 6 miesięcy to już nie jest tak nowa, dużo się uczę i dużo koduję. Między innymi używam sławnego jquery i ajaxa. Postanowiłem dołożyć obie rzeczy do django aby wszystko ładnie pięknie ze sobą współgrało. Założenie było proste, pewne elementy strony mają być dynamicznie odświeżane. W moim projekcie wyświetlam statystyki [...]<p><a
href="http://www.michalklich.com/2010/04/23/django-i-ajax/">Django i ajax</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>W mojej nowej pracy, pracuję tam 6 miesięcy to już nie jest tak nowa, dużo się uczę i dużo koduję. Między innymi używam sławnego jquery i ajaxa. Postanowiłem dołożyć obie rzeczy do django aby wszystko ładnie pięknie ze sobą współgrało. Założenie było proste, pewne elementy strony mają być dynamicznie odświeżane. W moim projekcie wyświetlam statystyki na stronie głównej używając właśnie ajaxa i jquery aby były one w miarę aktualne (w czasie rzeczywistym można rzec).<br
/> <span
id="more-709"></span><br
/> <strong>Info:  Django plus ajax. Jeśli mocniejszą stroną u Ciebie jest python niż javascript, może zainteresuje Cię <a
href="http://www.michalklich.com/2010/08/05/dajax-odpicuje-django/">Dajax</a>? Nie, to czytaj dalej.</strong><br
/> Pierwsze czego potrzebujemy to kod w pliku views.py (oczywiście z odpowiednim wpisem do urls.py)</p><pre class="brush: python; title: ; notranslate">def informacja(request):
    if request.is_ajax():
      return HttpResponse(u'Wywołanie ajax wykonano.')</pre><p>A kolejny kod to javascript który nam to ładnie obsłuży. W tym wypadku wsadzi do elementu div.</p><pre class="brush: jscript; title: ; notranslate">
$.ajax({
   type: 'POST',
    url: '/adres_do_uslugi',
   success: function(j) {
       $('#informator').html(j);
        }
});</pre><p>Tyle drodzy państwo. Naprawdę proste a możliwości niezliczone.<br
/> p.s.<br
/> Czy zna ktoś jakiś ciekawy plugin WordPress`a do prezentacji kodu?</p><p><a
href="http://www.michalklich.com/2010/04/23/django-i-ajax/">Django i ajax</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2010/04/23/django-i-ajax/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Jak dołączyć %changelog, %post_install i %post_uninstall do pliku spec używając distutils i setup.py</title><link>http://www.michalklich.com/2010/02/17/jak-dolaczyc-changelog-post_install-i-post_uninstall-do-pliku-spec-uzywajac-distutils-i-setup-py/</link> <comments>http://www.michalklich.com/2010/02/17/jak-dolaczyc-changelog-post_install-i-post_uninstall-do-pliku-spec-uzywajac-distutils-i-setup-py/#comments</comments> <pubDate>Wed, 17 Feb 2010 07:00:38 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[fedora]]></category> <category><![CDATA[linux]]></category> <category><![CDATA[open source]]></category> <category><![CDATA[programowanie]]></category> <category><![CDATA[distutils]]></category> <category><![CDATA[python]]></category> <category><![CDATA[rpm]]></category> <category><![CDATA[setup.py]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=672</guid> <description><![CDATA[Ostatnimi czasy moją głowę zaprzątał problem stworzenia paczki rpm dla mojego programu SynapticsConfig. Długo walczyłem z jednego powodu, chciałem użyć distutils a nie ręcznie tworzyć plik spec. Poniżej przytoczę problemy z którymi się borykałem oraz rozwiązania tych problemów. Wg. mnie dokumentacja distutils i pythona dotycząca zagadnień które poruszam jest dosyć skromna i wszelkie próby znalezienia [...]<p><a
href="http://www.michalklich.com/2010/02/17/jak-dolaczyc-changelog-post_install-i-post_uninstall-do-pliku-spec-uzywajac-distutils-i-setup-py/">Jak dołączyć %changelog, %post_install i %post_uninstall do pliku spec używając distutils i setup.py</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Ostatnimi czasy moją głowę zaprzątał problem stworzenia paczki rpm dla mojego programu SynapticsConfig. Długo walczyłem z jednego powodu, chciałem użyć distutils a nie ręcznie tworzyć plik spec. Poniżej przytoczę problemy z którymi się borykałem oraz rozwiązania tych problemów. Wg. mnie dokumentacja distutils i pythona dotycząca zagadnień które poruszam jest dosyć skromna i wszelkie próby znalezienia rozwiązania dawały mierne wyniki. Całe szczęście mamy listy dyskusyjne oraz od źródłowy (fuck you propietary software!).</p><p><span
id="more-672"></span></p><ol><li>Dołączanie %changelog</li><p>Część pliku spec odpowiedzialna za changelog jest wymagana, tak przynajmniej uważa rpmlint oraz tak stoi w dokumentacji Fedory. W <a
href="http://docs.python.org/distutils/setupscript.html">dokumentacji distutils</a> nie ma zbyt wielu informacji na ten temat. Jednak naprowadziła mnie ona na proste rozwiązanie a mianowicie</p><pre>python setup.py bdist_rpm --help</pre><p>Komenda wyświetla dokładnie to czego potrzeba czyli</p><pre>--changelog          RPM changelog</pre><p>To mogłoby załatwić sprawę gdyby nie brak informacji w jakiej postaci ma być changelog. Wszystko wskazuje, że to powinien być plik jednak <a
href="http://fedoraproject.org/wiki/Packaging:Guidelines#Changelogs">domyślne formatowanie</a> nie spełniało wymagań i ładnie wypluwało komunikat, że wiersz musi zaczynać się od &#8222;*&#8221;. Postanowiłem zerknąć do pliku odpowiedzialnego za generowanie paczek rpm /usr/lib64/python2.6/distutils/command/bdist_rpm.py. Na początku pliku wśród listy opcji pojawia się taki tekst</p><blockquote><p># More meta-data: too RPM-specific to put in the setup script,<br
/> # but needs to go in the .spec file &#8212; so we make these options<br
/> # to &#8222;bdist_rpm&#8221;.  The idea is that packagers would put this<br
/> # info in setup.cfg, although they are of course free to<br
/> # supply it on the command line.</p></blockquote><p>No ładnie ale ja z lini poleceń nie mogłem dołączyć changelog więc z pomocą przyszedł plik <a
href="http://docs.python.org/distutils/configfile.html">setup.cfg</a>. Do pustego pliku dodałem linijkę</p><blockquote><p>[bdist_rpm]<br
/> changelog = #tutaj tekst changelog oczywiście zaczynający się od *</p></blockquote><p>Należy pamiętać o gwiazdce ropoczynającej każdą wersję oraz o poprawnym formacie daty. Rpm jest bardzo wymagający w tym temacie. Tak przygotowany changelog powinen przejść proces budowania paczki.</p><li>Dodawanie %post_install i %post_uninstall</li><p>Kolejne rzeczy, które musiałem skonfigurować to sekcje kodu uruchamiane po zainstalowaniu paczki i jej odinstalowaniu. Wspomniany wcześniej bdist_rpm &#8211;help tak opisuje to</p><blockquote><div
id="_mcePaste">&#8211;post-install       Specify a script for the post-INSTALL phase of RPM</div><div
id="_mcePaste">building</div><div
id="_mcePaste">&#8211;post-uninstall     Specify a script for the post-UNINSTALL phase of RPM</div><div
id="_mcePaste">building</div></blockquote><p>W tym wypadku jednak nie używałem linii poleceń ani pliku setup.cfg. Te dwie opcje pozwoliły sie zgrabnie dołączyć do pliku setup.py jako argument funkcji setup</p><pre>options={'bdist_rpm' : {'post_install'  : 'ścieżka_do_pliku', 'post_uninstall'  : 'ścieżka_do_pliku'}}</pre><p>Bardzo możliwe, że zamiast podawania ścieżek do istniejących plików można wsadzić komendy. W wypadku skryptów mających parę linijek może pojawić się problem, ale nie testowałem.</ol><div>Mam nadzieję, że przybliżyło to co niektórych do stworzenia własnej paczki rpm przy użyciu distutils. To dlaczego wybrałem %post_install i %post_uninstall zostało podyktowane sposobem uruchamiania mojego programu i niemożliwością (spodowoaną może brakiem wystarczającej wiedzy) dodania linka do pliku w paczce rpm. Z wielką chęcią przyjmę wszelkie uwagi lub sugestie.</div><p><a
href="http://www.michalklich.com/2010/02/17/jak-dolaczyc-changelog-post_install-i-post_uninstall-do-pliku-spec-uzywajac-distutils-i-setup-py/">Jak dołączyć %changelog, %post_install i %post_uninstall do pliku spec używając distutils i setup.py</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2010/02/17/jak-dolaczyc-changelog-post_install-i-post_uninstall-do-pliku-spec-uzywajac-distutils-i-setup-py/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Odpicuj backintime</title><link>http://www.michalklich.com/2009/08/17/odpicuj-backintime/</link> <comments>http://www.michalklich.com/2009/08/17/odpicuj-backintime/#comments</comments> <pubDate>Mon, 17 Aug 2009 10:00:54 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[linux]]></category> <category><![CDATA[open source]]></category> <category><![CDATA[programowanie]]></category> <category><![CDATA[backup]]></category> <category><![CDATA[python]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=630</guid> <description><![CDATA[Jak wiadomo istnieją dwie grupy użytkowników, pierwsza robi kopie zapasowe a druga zacznie je robić. Ja przeszedłem do pierwszej i po dosyć długich poszukiwaniach znalazłem ciekawy program back-in-time, który załatwia za mnie tworzenie kopii zapasowych. Prosty i łatwy w obsłudze, idealnie nadaje się na desktopy. Jego jedyną wadą wg. mnie jest brak pakowania tworzonych katalogów [...]<p><a
href="http://www.michalklich.com/2009/08/17/odpicuj-backintime/">Odpicuj backintime</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Jak wiadomo istnieją dwie grupy użytkowników, pierwsza robi kopie zapasowe a druga zacznie je robić. Ja przeszedłem do pierwszej i po dosyć długich poszukiwaniach znalazłem ciekawy program <a
href="http://backintime.le-web.org/">back-in-time</a>, który załatwia za mnie tworzenie kopii zapasowych. Prosty i łatwy w obsłudze, idealnie nadaje się na desktopy. Jego jedyną wadą wg. mnie jest brak pakowania tworzonych katalogów z kopiami dlatego napisałem mały skrypt w pythonie, który załatwia to za mnie.</p><p>Jako argument bierze ścieżkę do katalogu w którym foldery musi spakować i po kolei pakuje do plików tar.bz2. Polecam dodanie do crontaba użytkownika root tak jak back-in-time.</p><p><a
href="http://www.michalklich.com/wp-content/uploads/2009/08/backintime-helper.py">Kod do pobrania</a>, oczywiście dostępny na licencji GPLv3.</p><p><a
href="http://www.michalklich.com/2009/08/17/odpicuj-backintime/">Odpicuj backintime</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2009/08/17/odpicuj-backintime/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Jak tłumaczyć łatwo w PyQt4 aplikacje</title><link>http://www.michalklich.com/2009/08/09/jak-tlumaczyc-latwo-w-pyqt4-aplikacje/</link> <comments>http://www.michalklich.com/2009/08/09/jak-tlumaczyc-latwo-w-pyqt4-aplikacje/#comments</comments> <pubDate>Sun, 09 Aug 2009 20:29:06 +0000</pubDate> <dc:creator>Michał</dc:creator> <category><![CDATA[linux]]></category> <category><![CDATA[programowanie]]></category> <category><![CDATA[PyQt4]]></category> <category><![CDATA[python]]></category> <category><![CDATA[tłumaczenie]]></category><guid
isPermaLink="false">http://www.michalklich.com/?p=586</guid> <description><![CDATA[Interesuję się od pewnego czasu pythonem a od niedawna PyQt4. Dokumentacja jest naprawdę dobre zrobiona, co prawda nie jest to msdn ale jest dobrze. Postanowiłem się zabrać za tłumaczenie aplikacji przy użyciu właśnie PyQt4, może lepiej napisać Qt4. Nie potrafiłem znaleźć nic pomocnego w internecie więc zabrałem sie za czytanie książek i teraz wiem i [...]<p><a
href="http://www.michalklich.com/2009/08/09/jak-tlumaczyc-latwo-w-pyqt4-aplikacje/">Jak tłumaczyć łatwo w PyQt4 aplikacje</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></description> <content:encoded><![CDATA[<p>Interesuję się od pewnego czasu pythonem a od niedawna PyQt4. Dokumentacja jest naprawdę dobre zrobiona, co prawda nie jest to msdn ale jest dobrze. Postanowiłem się zabrać za tłumaczenie aplikacji przy użyciu właśnie PyQt4, może lepiej napisać Qt4. Nie potrafiłem znaleźć nic pomocnego w internecie więc zabrałem sie za czytanie książek i teraz wiem i mam zamiar się podzielić z ludźmi którzy mają taki sam problem jaki miałem ja: brak przykładów i jasnych instrukcji jak użyć funkcji <em>tr()</em> i <em>translate()</em>.<br
/> <span
id="more-586"></span><br
/> Załóżmy, że posiadasz mały formularz stworzony w QtDesigner i dopisałeś do tego trochę swojego kodu.</p><pre class="brush: python; title: ; notranslate">
from PyQt4 import QtCore, QtGui
import sys
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName('MainWindow')
        MainWindow.resize(365, 222)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName('centralwidget')
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(110, 70, 114, 27))
        self.pushButton.setObjectName('pushButton')
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate('MainWindow', 'MainWindow', None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate('MainWindow', 'Click', None, QtGui.QApplication.UnicodeUTF8))
class MyForm(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
if __name__ == &quot;__main__&quot;:
    app = QtGui.QApplication(sys.argv)
    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())
</pre><p>Powyższy kod powstał już po edycji pliku z QTDesignera, do pliku wynikowego przetworzonego w pyuic4 dorzuciłem dwa dodatkowe bloki kodu. Inicjalizację formatki oraz klasę MyForm. Teraz ten plik zawiera całość kodu, który otwiera mini formatkę z jednym przyciskiem nad czym będziemy pracować. Pozwolę sobie omijać fragmenty kodu i podawać tylko istotne zmiany. Wiem, że w wypadku częstych zmian formatki lepiej jest ją trzymać w osobnym pliku i importować ale na potrzeby tego tutoriala jest to jeden plik.</p><p>Do pliku dodajemy kod podpinający sygnał <em>clicked()</em> do naszego przycisku i wykonujący stworzoną przez nas akcję. Dodajemy to do klasy MyForm.</p><pre class="brush: python; title: ; notranslate">
QtCore.QObject.connect(self.ui.pushButton, QtCore.SIGNAL('clicked()'), self.MessageBox)
</pre><p>Następnie piszemy funkcję MessageBox która wyświetli okienko potwierdzające, że akcja została wykonana.</p><pre class="brush: python; title: ; notranslate">
def MessageBox(self):
    box = QtGui.QMessageBox(self)
    box.setWindowTitle(self.tr('information'))
    box.setText(self.tr('You have clicked button'))
    box.setStandardButtons(QtGui.QMessageBox.Ok)
    box.exec_()
</pre><p>Ten plik po uruchomieniu wyświetli okno z jednym przyciskiem po kliknięciu którego wyświetli się messagebox. Teraz zabierzemy się za tłumaczenie programu. Przechodzimy do sedna.</p><p>Wymienione przeze mnie funkcje odpowiadają za tworzenie plików .ts do tłumaczeń. Konwencja używania funkcji jest następująca, <em>translate()</em> używane jest dla tekstów będących poza klasami (<em>QTDesigner</em> wszystko wsadza do funkcji <em>translate()</em>, funkcja wymaga podnia kontekstu w jakim znajduje sie łańcuch), funkcja <em>tr()</em> jest dla wszelkich łańcuchów będących w środku klas a <em>trUtf8()</em> dla łańcuchów UTF8. Proste jak drut a przykłady użycia są w kodzie.</p><p>Następnym krokiem jest zmodyfikowanie aplikacji aby ładowała tłumaczenie automatycznie na podstawie zmiennej &amp;LANG. Dodajemy kod do funkcji inicjalizującej (jako, że nie jestem pewny o czym piszę to mam na myśli <em>if __name__ == &#8222;__main__&#8221;:</em>)</p><pre class="brush: python; title: ; notranslate">
locale = QtCore.QLocale.system().name()
appTranslator = QtCore.QTranslator()
if appTranslator.load('okno_ui_' + locale):
    app.installTranslator(appTranslator)
</pre><p>Dzięki temu program będzie uruchamiał odpowiednie tłumaczenie, jeśli plik z tłumaczeniem nie zostanie odnaleziony zostanie załadowany domyślny język(w tym wypadku angielski gdyż taki został użyty w kodzie). Dla języka polskiego program będzie próbował załadować tłumaczenie z pliku okno_ui_pl_PL.qm. Nie jest konieczne dodawanie rozszerzenia .qm. Takich plików jeszcze nie mamy, najpierw należy stworzyć plik .pro zawierający wszelkie pliki .ui, .py, .pyw oraz .ts (co ładnie rozwija się w <em>translation source</em>). Ja zazwyczaj nie dodaję plików .ui z powodu tego, że formularze przerabiam potem troszkę na własną rękę poprawiając kod i później mam zamieszanie w pliku .ts. Trudno mi powiedzieć czy jest to dobra czy zła praktyka, mam zbyt małe doświadczenie. <span
style="text-decoration: underline;">Drobne uaktualnienie odnośnie dodawania plików .ui, w tej chwili jednak wolę trzymać formularz stworzony w QtDesigner w osobnym pliku, przyspiesza to dokonywanie zmian. Jednak dla potrzeb tego poradnika jest to wsadzone do jednego pliku, mniej plików = mniejsze zamieszanie.</span> Oto plik .pro.</p><pre class="brush: python; title: ; notranslate">
SOURCES = okno_ui.py
TRANSLATIONS = okno_ui_pl_PL.ts
</pre><p>W wypadku dodawania plików .ui potrzebna jest linijka FORMS =. Następnie wykonujemy polecenie <em>pylupdate4</em> a jako argument podajemy stworzony plik .pro i otrzymujemy gotowy plik .ts który mozna przetłumaczyć. Tłumaczenia robimy w programie QtLinguist, a gotowe pliki .ts przetwarzamy programem <em>lrelease-qt4</em> który tworzy nam pliki .qm. Koniec pracy. Jeśli w katalogu aplikacji znajdzie się plik .qm dla odpowiedniego języka systemowego to tłumaczenie zostanie załadowane w innym wypadku program otworzy się  w języku angielskim.</p><p>W wypadku jeśli chcemy dołożyć tłumaczenie nalęzy po prostu dodać odpowiedni plik .ts do posiadanego pliku .pro i ponownie uruchomić <em>pylupdate4, </em>QtDesigner<em>, lrelease-qt4</em> i tak w koło Macieju.</p><p>Dziękuję za uwagę.</p><p><a
href="http://www.michalklich.com/2009/08/09/jak-tlumaczyc-latwo-w-pyqt4-aplikacje/">Jak tłumaczyć łatwo w PyQt4 aplikacje</a> to wpis z <a
href="http://www.michalklich.com">FLLOGa</a></p> ]]></content:encoded> <wfw:commentRss>http://www.michalklich.com/2009/08/09/jak-tlumaczyc-latwo-w-pyqt4-aplikacje/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> </channel> </rss>
<!-- Served from: www.michalklich.com @ 2012-02-07 08:03:41 by W3 Total Cache -->
