Jesteśmy przyzwyczajeni do korzystania z GUI w wielu aplikacjach – począwszy od prostych programów na mikrokontroler, korzystających z wyświetlaczy TFT do komunikowania się z użytkownikiem, a kończąc na bardziej złożonych aplikacjach na PC. Oprogramowanie takie towarzyszy nam w domach (pralki, lodówki, itp.), w zakładach produkcyjnych (sterowanie maszynami za pomocą paneli operatorskich) i w niezliczonych innych obszarach techniki. Popularność GUI sprawia, że sama myśl, iż takiego interfejsu mogłoby zwyczajnie w świecie nie być, wydaje nam się nie do pomyślenia.
Czym jest GUI?
GUI to nic innego, jak skrót od Graphic User Interface, czyli – w dosłownym tłumaczeniu – graficzny interfejs użytkownika. GUI stanowi swego rodzaju pomost pomiędzy aplikacją a użytkownikiem, pozwalając na łatwe i szybkie kontrolowanie zachowania systemu przez eksploatatora. Należy tu zauważyć, że nie zawsze jesteśmy w stanie przewidzieć zachowanie aplikacji, zwłaszcza jeśli zostaną dostarczone do niej niepoprawne dane wejściowe. W takich przypadkach najczęściej aplikacja będzie zabezpieczona przez programistę w samym kodzie źródłowym. Mówiąc w wielkim skrócie – GUI zwalcza użytkownikowi na szybkie i proste kontrolowanie aplikacji, systemu wbudowanego czy też maszyny.
Tworzenie aplikacji
Jedną z najprostszych możliwych aplikacji na mikrokontroler jest zaświecenie diody LED, co robiliśmy już zresztą we wcześniejszych odcinkach tego kursu. Tym razem jednak połączymy kod z wcześniejszych części niniejszego cyklu z pewnymi ulepszeniami i modyfikacjami.
Stworzymy prosty interfejs użytkownika, wyposażony w przełącznik suwakowy pozwalający nam na kontrolowanie stanu diody LED. Aplikacja zostanie napisana w języku Python, z uwagi na łatwość pisania skryptu i jego niewielką objętość.
Kod aplikacji widoczny jest na listingu 1.
# Wymaganie wersji GTK 3.0
gi.require_version(„Gtk”, „3.0”)
from gi.repository import Gtk # Import modułu GTK
def set_led(state):
„””
Funkcja zmienia stan diody LED systemowej poprzez zapis do pliku brightness.
Parametr:
state (int): 1 – włączenie LED, 0 – wyłączenie LED.
„””
try:
with open(„/sys/class/leds/heartbeat/brightness”, „w”) as led:
led.write(str(state)) # Zapis stanu diody LED do pliku systemowego
except IOError as e:
print(f”Error accessing LED file: {e}”) # Obsługa błędu w przypadku problemu z dostępem do pliku
def on_switch_activated(switch, gparam):
„””
Obsługuje zdarzenie zmiany stanu przełącznika.
Parametry:
switch (Gtk.Switch): Obiekt przełącznika GTK.
gparam: Nieużywany parametr przekazywany przez sygnał.
„””
state = 1 if switch.get_active() else 0 # Sprawdzenie, czy przełącznik jest aktywny (włączony)
set_led(state) # Ustawienie stanu LED
print(„Switch was turned”, „on” if state else „off”) # Wypisanie aktualnego stanu
# Tworzenie głównego okna aplikacji
win = Gtk.Window(title=”LED Control”)
win.set_border_width(10) # Ustawienie marginesu wokół zawartości okna
win.connect(„destroy”, Gtk.main_quit) # Zamknięcie aplikacji po zamknięciu okna
# Tworzenie poziomego kontenera Box dla elementów interfejsu
hbox = Gtk.Box(spacing=6)
win.add(hbox) # Dodanie Box do głównego okna
# Tworzenie przełącznika (Switch) i podłączenie funkcji obsługującej zmianę stanu
switch = Gtk.Switch()
switch.connect(„notify::active”, on_switch_activated) # Reakcja na zmianę stanu przełącznika
hbox.pack_start(switch, True, True, 0) # Dodanie przełącznika do kontenera Box
# Wyświetlenie wszystkich elementów interfejsu
win.show_all()
Gtk.main() # Uruchomienie głównej pętli GTK
Listing 1. Kod skryptu
Wgranie kodu do pamięci i uruchomienie
Do wgrania naszej aplikacji na płytkę rozwojową używamy polecenia scp, znanego z wcześniejszych części kursu. Uruchomienie aplikacji również odbywa się w sposób analogiczny do tego, który opisaliśmy wcześniej.
Efektem działania prostego programu z listingu 1 będzie zaświecenie diody LED – suwak w pozycji załączonej jest widoczny na fotografii 1, a w pozycji nieaktywnej – na fotografii 2.
Warto również zwrócić uwagę na wyświetlające się w terminalu komunikaty o załączeniu lub zgaszeniu naszej diody LED (fotografia 3).
Takiego rodzaju logi często są przydatne w przypadku większych aplikacji, ponieważ pozwalają nam na kontrolowanie działania aplikacji i diagnostykę ewentualnych problemów. Należy pamiętać, że nie wszystkie informacje są umieszczane w GUI – spora ich część ląduje często w logach systemowych.
inż. Wiktor Hubaj