system-tray

[Kurs QT] Aplikacja chowana w system tray

Wstęp


W tej części kursu napiszemy sobie aplikację, którą można będzie schować w zasobniku systemowym (chyba w ten sposób się ładnie tłumaczy na polski), mam nadzieję, że nie jesteście strasznymi miłośnikami naszego nielogicznego języka, ale ja będę używał w tym kursie angielskiego odpowiednika, czyli system tray (jest to spowodowane kilkoma powodami, ale nie będę ich tutaj wymieniał).

 

Czym jest system tray?


Jest to nic innego jak zasobnik ikon aplikacji, które obecnie działają w tle, ale nie jest rysowane ich okno, a ten zasobnik daje nam możliwość szybkie wywołanie okna takiej aplikacji (tak to te ikonki standardowo obok zegarka).

 

Chowanie aplikacji to tray’a


Sama funkcjonalność chowania ikony aplikacji do system tray jest nieco zaszyta w samym Qt, lecz na szczęście można się do niej dostać w nieszczególnie trudny sposób, ale zanim dojdziemy do tego to standardowo stwórzmy sobie jakieś okno i program, który będzie coś robił.

Nasz program nie robi wiele, bo potrafi jedynie się chować (wybaczcie mi brak praktycznego pomysłu, na to co mógłby robić).

O ile schować okno jest dość łatwo, to przydałoby się mimo wszystko dać możliwość użytkownikowi do aktywowania ponownie okna, dlatego musimy dołączyć nową bibliotekę: QSystemTrayIcon.

W mainwindow.h dopisujemy:

Jeżeli wcześniej ustawiliśmy sobie w edytorze projektu jakąś ikonę (mamy ją w pliku zasobów) to możemy łatwo ustawić ją także do ikony traya.

Ja użyłem ikonę na licencji CC0, właśnie tej licencji :P. Gdy teraz uruchomimy program mamy już 50% tego co chcieliśmy osiągnąć! Aplikacja posiada już własny tray, tylko że obecnie nic nie możemy nim manipulować, po prostu jest.

Kolejnym krokiem będzie sprawienie że aplikacja zniknie i się pojawi, znikanie jest banalne w wykonaniu i dość oczywiste, jeżeli w edytorze klikniemy PPM na przycisk Hide i wybierzemy opcję „Go to slot” to wygeneruje nam się gotowa funkcja, którą trzeba uzupełnić:

Teraz jeżeli uruchomisz aplikację i wciśniesz przycisk „Hide” to aplikacji nie będzie dało się wywołać z powrotem na ekran, a gdybyśmy nie ustawili ikony traya i wstawili powyższą funkcję to nasza aplikacja byłaby niemalże niewidzialna, prawdziwy ninja! (w menadżerze zadań byłaby widoczna).

Teraz najwyższy czas powiedzieć naszemu programowi: „hej, super że jesteś w trayu, ale chciałbym z powrotem zobaczyć twoje okno”.

Wracamy do konstruktora, gdzie zaraz pod ustawieniem wskaźnika na trayIcon piszemy:

connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(show()));

Tyle? Tyle, teraz czujemy moc Qt, widzimy z jaką łatwością możemy dodawać nowe elementy, widzimy jak ta biblioteka jest przyjazna użytkownikowi, aż chce się powiedzieć „how cool is that”.

thinking meme

Teraz pewnie się zastanawiasz: „Ok, to było proste, ale przecież aplikacje posiadają własne menu kontekstowe, które się wywołuje po kliknięciu prawego przycisku myszy, co wtedy?”.

Tutaj przyznaję ci rację, obecnie nasza przy dowolnie jakim kliknięciu (LMB,RMB,MMB) powoduje odsłonięcie naszego okienka, nie mamy żadnego menu, ale nic nie stoi na przeszkodzie aby je sobie napisać.

 

Menu kontekstowe tray’a


Tak dla ogólnej wiadomości: menu kontekstowe robi się analogicznie do menu kontekstowego ogólnie, ale że nigdzie tego nie pokazywałem więc czas nadrobić zaległości.

Wracamy się do mainwindow.h, gdzie musimy dopisać kilka pozycji (przy okazji plik w całej okazałości):

Dodaliśmy 1 slot, który będzie odpowiedzialny za odpowiednie akcje do tego jak zadziała na naszej ikonie użytkownik. Mamy także wspomniane akcje do menu kontekstowego: maksymalizacje, minimalizacje, pokazanie i zamknięcie okna.

Teraz w konstruktorze musimy dodać/pozmieniać parę rzeczy (no więcej niż parę):

Konfigurujemy tutaj i łączymy akcje z menu kontekstowym itp. W zasadzie dużo łatwego do zrozumienia kodu. Zmieniliśmy także wcześniej połączone pokazywanie okna po jakimkolwiek kliknięciu na nasz slot.

Ustawiliśmy sobie, że po podwójnym kliknięciu aplikacja ma się pojawiać, po kliknięciu środkowego ma się minimalizować, pod prawy przycisk nic nie ustawiamy bo to jest domyślny przycisk pod menu kontekstowe.

Mamy już kolejną część układanki i zauważamy, że temat tray’a systemowego jest już niemal wyczerpany, a mianowicie brakuje nam jeszcze chmurki, która komunikuje nas o np. stanie aplikacji. Na pewno kojarzysz chmurkę o odłączeniu/podłączeniu słuchawek, czy mikrofonu. Właśnie czymś takim się zajmiemy.

 

 

Wiadomość (chmurka)


Tutaj możemy wyróżnić 2 sytuacje: po kliknięciu chmurki coś się dzieje (zostaje przywrócone okno z otwartą rozmową osoby która do nas pisze jak w skype), albo nic się nie dzieje i wtedy nie musimy pisać sobie slotu na kliknięcie chmurki. My jesteśmy jednak tak zdolni i tak ambitni, że napiszemy wersję rozszerzoną 😉

Więc w pliku mainwindow.h dopisujemy sloty.

W konstruktorze dopisujemy przy łączeniu eventów:

connect(trayIcon,SIGNAL(messageClicked()),this,SLOT(messageClicked()));

Tutaj sygnał i slot to dwie różne funkcje, po prostu mamy zbieżność nazw. Ustawimy sobie także po kliknięciu LMB na ikonie wywołanie chmurki (w iconActivated()):

Teraz zdefiniujmy nasze pokazywanie wiadomości i tego co się stanie po kliknięciu na nią:

Dodam jeszcze, że showMessage jako opcjonalne argumenty przyjmuje ikonę i czas wyświetlania wiadomości w ms.


  • Wielkie gratulacje i podziękowania dla tych co czekali na kolejną lekcję tego kursu prawie 2 miesiące 😀 Dajcie znać o czym chcecie przeczytać w kolejnej części kursu za kolejne 2 miesiące (żart (chyba 😛 ) )

  • Wollier

    Mógłbyś napisać coś o slotach. Jak pobrać zawartość z textboxa, jak wczytać obrazek, itp.

    • Co nieco o slotach mogę napisać, ale pozostałe rzeczy były napisane „przy okazji”, nie widzę sensu nad rozwodzeniem się w całym artykule jak pobrać zawartość textboxa, gdzie używamy jednej metody. Bardziej mi zależy na pokazaniu mnie standardowych funkcji tej biblioteki, a te co są już zaimplementowane pokazuję przy okazji. Poradnik z rozbicie QT na czynniki pierwsze napisał Mateusz „Matthew” Marek.

  • morsisko

    Cześć mam jedno pytanie, może niekoniecznie skierowane do tej części tutoriala tylko ogólnie, do całego QT. Otóż stworzyłem program który chciałbym udostępnić, bez żadnych opłat – za darmo, jednak czytałem trochę o tych licencjach i już się pogubiłem. Więc tutaj moje pytanie, czy takie udostępnianie jest dozwolone? A może muszę dokupić „pełną wersję” QT? Czytałem gdzieś też, że wystarczy dodać w dokumencie z jakiej licencji się korzysta. Jednak to wszystko wydaję mi się bardzo zagmatwane.

    PS. Tutorial świetny, właśnie o takie coś mi chodziło, a nigdzie nie mogłem tego znaleźć. 🙂

    • Musisz dodać plik z licencją, z której skorzystasz i tak jak pisze na stronie QT twoja licencja musi być zgodna z którąś z tych licencji: GPL, LGPL v2.1, LGPL v3