niedziela, 7 maja 2017

Status bar.

Obecność status bar'a nie jest obowiązkowa, ale wydaje się, że pomaga w pewien sposób przekazywać użytkownikowi informacje, dotyczące działania aplikacji. Budując okno programu miałem w planach dodanie status bar'a, ale zakodowanie tej funkcjonalności odkładałem w czasie, gdyż nie była ona krytyczna dla funkcjonowania całego programu.

Wyświetlanie statusów następuje poprzez, zmianę wartości odpowiedniej instancji klasy StringVar() w widget'cie ttk.Label. Bardzo istotnym założeniem było wyświetlanie danej wiadomości tylko przez określony okres czasu, a następnie czyszczenie całego paska. Kolejkowanie zadań w Tkinter odbywa się poprzez zastosowanie metody "after" na jakimś widget'cie. Piszę jakimś, ponieważ implementując to rozwiązanie dostrzegłem, że instancja widget'a nie musi należeć do tej samej hierarchii. Jednak dla zachowania jednorodności, wszystkie wywołania metody "after" przypisywałem do tego samego obiektu. W metodzie tej przekazuje się czas (w milisekundach) po jakim ma zostać wywołana dana funkcja oraz przekazuje się samą funkcję.

self.canvas_frame.after(2000, self.clear_status)

Okazało się, że częściowo myliłem się odnośnie funkcjonowania tej metody. Nie wiedziałem, że kolejne jej wywołanie, nie anuluje automatycznie poprzedniego. Zamiast tego, kolejne wywołania są kolejkowane i wywoływane po odpowiednim upływie czasu. Jeśli zdefiniowane interwały są niewielkie nie sprawia to problemu, aczkolwiek przy zastosowaniu okresu 2000 ms, mogą dziać się ciekawe rzeczy. Użyłem tego rozwiązania do wyświetlania liczby odpowiadającej wielkości markera, po zmianie jego wielkości za pomocą skrótów klawiaturowych (oraz odpowiadających przycisków). Przy zmianie wielkości o kilka stopni, następowało kolejkowanie zadań i ich wywoływanie po odpowiednim czasie, co kilkukrotnie, w niewielkich odstępach czasu, czyściło status bar'a. Spowodowało to migotanie tekstu wyświetlanego na status bar'ze. Być może uszło by to uwadze większości użytkowników, jednak w pewien sposób wskazywało na kiepską jakość kodu w programie. Było też nie estetyczne.

Jak zwykle szukałem rozwiązań w internecie, głównie na "stacku". Najprostszym z nich było utworzenie atrybutu klasy, do którego przypisywane było aktualne zadanie, "self.job_queue". Jeśli atrybut ten posiadał wartość "None", przypisywano do niego pierwsze zadanie. Jeśli zadanie to zostało wykonane, wartość zostawała ponownie zmieniana na "None". Jeśli natomiast, przed wykonaniem zadania została ponownie wywołana metoda "after", to poprzednie zadanie było anulowane za pomocą metody "after_cancel", a do "self.job_que", przypisywano nowe zadanie. W ten sposób status bar zostawał czyszczony tylko raz, 2000 ms po wyświetleniu ostatniego tekstu, problem migotania został rozwiązany.

Brak komentarzy:

Prześlij komentarz