Przyciski a sprawa GTKmm3
14.06.2012 | aktual.: 15.06.2012 19:57
Tytuł tego wpisu nawiązuje do popularnych niegdyś zwrotów „(cośtam) a sprawa polska”, czyli wracamy do tematyki GTKmm3. Jak już w temacie wspomniałem, zajmiemy się przyciskami. Uwzględnię dwa typy: Button i ToggleButton.
Klasyczne przyciski
Najpierw zajmiemy się klasycznymi przyciskami - obiektami klasy Gtk::Button., które będą wywoływać odpowiednie funkcje.
Interfejs
Tutaj można zająć się interfejsem za pomocą Glade lub napisać odpowiedni zestaw linijek kodu, dzięki któremu zyskamy interfejs. Zajmiemy się pierwszym podejściem.
Wczytujemy plik interfejsu (w samym Glade lub wewnątrz Anjuta) i robimy układ Siatka (ang. Grid). Ustawiamy 3×3 komórki. Odstęp 5 jednostek od każdej komórki układu. W górnym wierszu (rzędzie) etykiety opisujące spinnery, w rzędzie/wierszu niżej przyciski z etykietą „Start”, a na samym dole spinnery. Całość wygląda tak:
Kod
Czas na kodzenie!
Najpierw zadeklarujemy wskaźniki na obiekty typu Gtk::Spinner oraz typu Gtk::Button. Dlaczego wskaźniki? Ponieważ jest to potrzebne do importu widżetów z pliku interfejsu.
Przykładowa deklaracja:
Gtk::Spinner *spin1, *spin2, *spin3; Gtk::Button *on1, *on2, *on3;
Deklaracja musi się znaleźć bezpośrednio przed funkcją main(int argc, char *argv[]).
Następnie wczytamy odpowiednie obiekty z pliku interfejsu:
builder->get_widget("button1", on1); builder->get_widget("button2", on2); builder->get_widget("button3", on3); builder->get_widget("spinner1", spin1); builder->get_widget("spinner2", spin2); builder->get_widget("spinner3", spin3);
Teraz połączymy sygnały zdarzenia kliknięcia na przycisk z odpowiednimi funkcjami.
on1->signal_clicked().connect(sigc::ptr_fun(&spinning1)); on2->signal_clicked().connect(sigc::ptr_fun(&spinning2)); on3->signal_clicked().connect(sigc::ptr_fun(&spinning3));
A oto poniższe funkcje:
void spinning1() { if(on1->get_label()=="Start") { spin1->start(); on1->set_label("Stop"); } else { spin1->stop(); on1->set_label("Start"); } } void spinning2() { if(on2->get_label()=="Start") { spin2->start(); on2->set_label("Stop"); } else { spin2->stop(); on2->set_label("Start"); } } void spinning3() { if(on3->get_label()=="Start") { spin3->start(); on3->set_label("Stop"); } else { spin3->stop(); on3->set_label("Start"); } }
W każdym ze zdarzeń sprawdzamy, czy etykieta przycisku to „Start”. Jeżeli tak jest, spinner zostaje uaktywniony (kręci się), a etykieta zmienia się na „Stop”. W przeciwnym wypadku spinner jest zatrzymywany, a etykieta wraca do stanu początkowego.
Demonstracja
Toggle Button
Tutaj zajmiemy się innym typem przycisku, ale przykładowy program będzie modyfikacją poprzedniego.
Na czym polega ta modyfikacja?
Zmieniamy typ przycisku w kodzie i w okienku na ToggleButton.
Usuwamy przyciski i wybieramy te z typu Gtk::ToggleButton (ikona obok ikony przycisku, czyli druga od lewej). Każdy z przycisków dostanie etykietkę „Spinning mode”. Akcje zostaną oprogramowanie następująco (zamiast tych poprzednich):
on1->signal_toggled().connect(sigc::ptr_fun(&spinning1)); on2->signal_toggled().connect(sigc::ptr_fun(&spinning2)); on3->signal_toggled().connect(sigc::ptr_fun(&spinning3));
Każda z funkcji będzie wyglądać następująco:
void spinning1() { if(on1->get_active()) { spin1->start(); } else { spin1->stop(); } } void spinning2() { if(on2->get_active()) { spin2->start(); } else { spin2->stop(); } } void spinning3() { if(on3->get_active()) { spin3->start(); } else { spin3->stop(); } }
Tutaj sprawdzamy, czy dany przycisk jest wciśnięty. Jeżeli tak, spinner kręci się, a w przeciwnym wypadku stoi.
Poniżej umieszczam demonstrację: [youtube=http://www.youtube.com/watch?v=SMGyH-YeH8s]
Podsumowanie
- W końcu poznaliśmy nowe sygnały, które można obsłużyć i nowe właściwości obiektów (na pewno dla ciekawskich początkujących).
- Mamy inny układ elementów w oknie niż ten z dwóch poprzednich wpisów.
- Już wiemy jak zrobić zabawkę dla zwierzaka/dziecka/studenta w czasie sesji/absolwenta szkoły średniej po maturach :D