Wykład IX - semestr II Kierunek Informatyka Wydział Matematyki Stosowanej Politechniki Śląskiej Gliwice, 2014 c Copyright 2014 Janusz Słupik
Biblioteka FLTK FLTK - Fast Light Toolkit - biblioteka GUI, napisana w C++ międzyplatformowa, Unix/Linux/Windows/MacOS, dostępna pod różne kompilatory, szybkość i prostota, pełna zgodność ze standardem C++, współpraca z OpenGL (tryb 3D), licencja GNU GPL, narzędzie FLUID do projektowania UI.
Alternatywa do FLTK Aplikacje okienkowe w C++ możemy tworzyć również przy użyciu: biblioteka Qt - wieloplatformowa (również pod systemy Symbian i Windows CE), gtkmm (GTK+) - wieloplatformowa, biblioteka windows.h tylko pod Windows, C++/CLI tylko pod Windows i kompilatory Visual C++, brak zgodności ze standardem C++. Jest uznawany za osobny język.
Zasoby Strona domowa projektu: http://www.fltk.org/ Wersja stabilna: fltk - 1.3.2
Instalacja pod MS Visual Studio Rozpakuj fltk-1.3.2-source.tar.gz. Z podkatalogu \MojeC\fltk-1.3.2\ide\VisualC2010 uruchom fltk.sln. Wykonaj Rebuild solution w trybie Debug i Release. W podkatalogu lib pojawi się 7 plików: fltk.lib, fltkforms.lib, fltkgl.lib, fltkimages.lib fltkjpeg.lib, fltkpng.lib, fltkzlib.lib oraz odpowiedniki tych plików dla trybu Debug kończące się literą d np.: fltkd.lib Skopiuj je do katalogu bibliotek kompilatora: C:\Program Files\Microsoft Visual Studio 10.0\VC\lib Podkatalog FL, który zawiera wszystkie niezbędne pliki nagłówkowe skopiuj do odpowiedniego katalogu kompilatora: C:\Program Files\Microsoft Visual Studio 10.0\VC\include
Instalacja pod Dev C++ (wersja 4.9.9.2) Uruchom Dev-C++ Z menu Narzędzia wybierz Sprawdź, czy są nowe uaktualnienia/pakiety... W nowo otwartym oknie zmień: Select devpak server na devpaks.org Community Devpaks. Następnie kliknij: Check for updates. Znajdź fltk w wersji 1.1.9 i zaznacz. Następnie kliknij: Download selected. Po ściągnięciu pakietu uruchomi się jego instalator. Zainstaluj pakiet.
Stworzenie nowego projektu FLTK w Dev-C++
Stworzenie nowego projektu FLTK w Dev-C++ Czasami trzeba wskazać linkerowi dodatkowe biblioteki:
Stworzenie nowego projektu FLTK w MS VS Stwórz New project dla Visual C++ z szablonu Win32 Project W oknie Application Wizard w części Application Settings ustaw Empty project i kliknij Finish. Uruchom z menu Project właściwości projektu <Nazwa projektu> properties. W tym oknie rozwiń Configuration properties a następnie Linker. Ustaw konfigurację: All configurations Kliknij pozycję Input a następnie w polu Additional Dependencies wpisz dla Debug: fltkd.lib; fltkjpegd.lib; fltkimagesd.lib; dla Release: fltk.lib; fltkjpeg.lib; fltkimages.lib;
Stworzenie nowego projektu FLTK w MS VS
Kompilacja w systemie Linux Po zainstalowaniu pakietów dla FLTK (odpowiednich dla używanej dystrybucji) najprostszym sposobem kompilacji jest uruchomienie: fltk-config --compile nazwa_pliku.cpp
Pierwszy program #include <FL/Fl.H> #include <FL/Fl_Window.H> int main() { Fl_Window w( 600, 400, "Nazwa okna" ); w.end();//zakończenie dodawania składników okna w.show(); } return Fl::run(); Zakończenie programu: kliknięcie krzyżyka, lub naciśnięcie klawisza Escape
Pierwszy program Równoważnie ze wskaźnikami: #include <FL/Fl.H> #include <FL/Fl_Window.H> int main() { Fl_Window *w = new Fl_Window(600,400,"Nazwa okna"); w->end(); } w->show(); return Fl::run();
Pierwszy program - działanie - tryb Debug MS VS
Czarne okno konsoli Okno konsoli nie pojawia się w projekcie tworzonym w Dev-C++, natomiast w MS VS, aby go nie było należy zmienić ustawienia linkera (zobacz dalej) oraz zamiast funkcji main() napisać: #include <windows.h> #include <FL/Fl.H> #include <FL/Fl_Window.H> int stdcall WinMain(HINSTANCE a, HINSTANCE b, char* c, int d) { Fl_Window window( 300, 180, "Okienko" ); window.end(); window.show(); } return Fl::run(); Uwaga. W przypadku tego kodu tracimy uniwersalność (wieloplatformowość) źródła na rzecz systemu Windows.
Czarne okno konsoli - c.d. W konfiguracji Linker w sekcji System ustawić:
Komponent okna - kontrolka - widget Okno może zawierać różnego rodzaju komponenty (przyciski, suwaki, itp.) Większość komponentów dziedziczy po klasie Fl Widget i ma następujący konstruktor: Fl_Nazwa(x, y, width, height, label) Napis Nazwa należy zastąpić nazwą komponentu. Etykieta label jest opcjonalna. Aby użyć takiego komponentu należy dodać: #include <FL/Fl_Nazwa.H>
Przykład - Fl Box #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Box.H> int main() { Fl_Window w(600, 400, "Nazwa okna"); Fl_Box b(20, 40, 260, 100, "Witam"); b.box( FL_UP_BOX ); //wypukłe obramowanie (FL_DOWN_BOX) b.labelsize( 36 ); //rozmiar czcionki w etykiecie b.labelfont( FL_BOLD+FL_ITALIC );//typ fontu b.labeltype( FL_SHADOW_LABEL ); //cieniowanie etykiety } w.end(); w.show(); return Fl::run();
Okno z Fl Box
Polskie znaki Wszystkie polecenia biblioteki FLTK (wersja 1.3.2) przyjmują łańcuchy znaków w kodowaniu UTF-8. Zatem można napisać: char s[100]; fl_utf8fromwc( s, sizeof(s), L"Cześć żółwik", sizeof(l"cześć żółwik")); Fl_Window w(600, 400, s); Fl_Box b(20, 40, 260, 100, s); char nowy[100]={0}; fl_utf_toupper( (unsigned char*) s, strlen(s), nowy);
Przyciski #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Button.H> #include <FL/Fl_Light_Button.H> #include <FL/Fl_Round_Button.H> #include <FL/Fl_Check_Button.H> #include <FL/Fl_Return_Button.H> int main() { Fl_Window okno(300, 350, "Okienko"); Fl_Button a(10, 40, 60, 30, "Oblicz"); Fl_Light_Button b(10, 100, 80, 30, "Akcja"); Fl_Round_Button c(10, 150, 80, 30, "Opcja"); Fl_Check_Button d(10, 200, 80, 30, "Zaznacz"); d.set(); Fl_Return_Button e(10, 250, 120, 30, "Tak"); okno.end(); okno.show(); return Fl::run(); }
Przyciski
Kolory Różne komponenty posiadają metodę ustawiającą ich kolor. Fl_Window okno(300,350,"okienko"); okno.color( FL_YELLOW ); Fl_Button a(10,40,60,30,"oblicz"); a.color( FL_GREEN ); a.color2( FL_RED ); Niektóre komponenty mają możliwość ustawienia drugiego koloru, który określa inny stan tego komponentu lub kolor jakiejś jego części, np. Fl Button przyjmuje ten kolor w momencie gdy jest wciśnięty, w Fl Check Button jest to kolor znaku zaznaczenia.
Kolory Możemy definiować własne kolory. Fl_Window okno(300,350,"okienko"); Fl_Color mojkolor = fl_rgb_color(85, 170, 255); okno.color( mojkolor );
Właściwości okno.size( 400, 400 ); Włączenie skalowalności okna okno.resizable( okno ); box.resize( 50, 50, 40, 40 ); Zamiana etykiety. Dla okna będzie to równoznaczne ze zmianą nazwy okna. Dla przycisku będzie to zmiana jego opisu. box.label( "Inna" );
Tekst #include <FL/Fl_Input.H> #include <FL/Fl_Output.H> #include <FL/Fl_Multiline_Output.H> #include <FL/Fl_Multiline_Input.H> Fl_Input in1(80, 40, 150, 30, "Nazwisko "); in1.value( "Kowalski" ); Fl_Output out1(80, 100, 150, 30, "Etykieta "); out1.value( "Nie do edycji" ); Fl_Multiline_Input in2(80, 150, 150, 130, "Multi 1 "); in2.value( "Wieloliniowy\ntekst" ); Fl_Multiline_Output out2(320, 150, 150, 130, "Multi 2 "); out2.value( "Nie do edycji\nwieloliniowy\ntekst" );
Tekst
Wieloliniowy tekst #include <FL/Fl_Text_Display.H> #include <FL/Fl_Text_Editor.H> Tego typu wieloliniowe komponenty tekstowe wymagają buforowania tekstu w obiekcie klasy Fl Text Buffer. Fl_Text_Display td(20,30,150,100,"etykieta"); Fl_Text_Buffer *napis = new Fl_Text_Buffer(); napis->append( "Tekst\nwieloliniowy" ); td.buffer( napis ); td.textfont( FL_BOLD ); Fl_Text_Editor te(220,30,150,100,"etykieta 2"); te.buffer( napis ); te.textcolor( FL_BLUE );
Wieloliniowy tekst
Menu - część I
Menu - część II #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Menu_Bar.H> void moja( Fl_Widget*, void* v ) { /*... */ } Fl_Menu_Item menuitems[] = { { "Program", 0, 0, 0, FL_SUBMENU }, { "&Pozycja", FL_CTRL + p, (Fl_Callback *)moja }, { "Inna", 0, (Fl_Callback *)moja, 0, FL_MENU_DIVIDER }, { "Koniec", 0, (Fl_Callback *)moja }, { 0 }, { "Opcje", 0, 0, 0, FL_SUBMENU }, { "&Ustawienia", FL_CTRL + u, (Fl_Callback *)moja }, { 0 }, };
Menu - część III int main() { Fl_Window w(600,400,"nazwa okna"); Fl_Menu_Bar m(0, 0, 600, 30); m.copy( menuitems ); w.end(); } w.show(); return Fl::run();
Obsługa kliknięcia przycisku - część I
Obsługa kliknięcia przycisku - część II #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Button.H> #include <FL/Fl_Input.H> #include <FL/Fl_Multiline_Output.H> #include <string> using namespace std; Fl_Input *input; Fl_Multiline_Output *multiout; void moja_cb(fl_widget*, void* v) { string n = multiout->value(); if( multiout->size() ) n += "\n"; n += input->value(); multiout->value( n.c_str() ); input->value(""); }
Obsługa kliknięcia przycisku - część III int main() { Fl_Window w(600,400,"nazwa okna"); input = new Fl_Input(80, 20, 150, 30, "Linia "); input -> value(""); multiout = new Fl_Multiline_Output(80,150,150,130,"Wszystko"); multiout -> value(""); Fl_Button p(260, 22, 90, 25, "Dodaj"); p.callback((fl_callback *)moja_cb); w.end(); w.show(); return Fl::run(); }
Przechwytywanie zdarzeń myszki - część I
Przechwytywanie zdarzeń myszki - część II #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Box.H> #include <FL/Fl_Input.H> #include <cstdio> using namespace std; Fl_Input *ix; Fl_Input *iy; class Area : public Fl_Box { public: int handle(int); Area(int x,int y,int w,int h) : Fl_Box(x,y,w,h) { } };
Przechwytywanie zdarzeń myszki - część III int Area::handle(int e) { static int x = 0, y = 0; char s[10]; if( e == FL_PUSH ) { x = Fl::event_x(); y = Fl::event_y(); sprintf( s, "%d", x-this->x() ); ix->value( s ); sprintf( s, "%d", y-this->y() ); iy->value( s ); return 1; } return 0; }
Przechwytywanie zdarzeń myszki - część IV int main() { Fl_Window w(600, 400, "Myszka"); Area b(10, 100, 580, 290); b.box( FL_UP_BOX ); ix = new Fl_Input(100, 20, 150, 25, "x: "); ix -> value(""); iy = new Fl_Input(300, 20, 150, 25, "y: "); iy -> value(""); } w.end(); w.show(); return Fl::run();
Obsługa klawiatury - część I #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Box.H> class Area : public Fl_Box { public: int handle(int); Area(int x,int y,int w,int h) : Fl_Box(x,y,w,h) { } };
Obsługa klawiatury - część II int Area::handle(int e) { int r = Fl::event(); if( r == FL_SHORTCUT ) // zdarzenie klawiatury { // inne: FL_KEYDOWN, FL_KEYUP int k = Fl::event_key(); switch( k ) { case FL_Up: label( "Up" ); break; case FL_Down: label( "Down" ); break; case FL_Left: label( "Left" ); break; case FL_Right: label( "Right" ); break; case 32: label( "Spacja" );break; } default: label( "Nieznany" ); } return 1; } return 0;
Obsługa klawiatury - część III int main() { Fl_Window window(300, 300, "Klawiatura"); Area box(20, 40, 260, 100); box.label( "Start" ); box.box( FL_UP_BOX ); box.labelsize( 36 ); box.labelfont( FL_BOLD + FL_ITALIC ); window.end(); window.show(); } return Fl::run();
Nazewnictwo klawiszy FL_Escape, FL_BackSpace, FL_Tab, FL_Enter, FL_Print, FL_Scroll_Lock, FL_Pause, FL_Insert, FL_Home, FL_Delete, FL_End, FL_Page_Up, FL_Page_Down, FL_Left, FL_Up, FL_Right, FL_Down, FL_Shift_L, FL_Shift_R, FL_Control_L, FL_Control_R, FL_Caps_Lock, FL_Alt_L, FL_Alt_R, FL_Num_Lock,
Rysowanie - część I #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Draw.H> class Rysunek : public Fl_Widget { void draw( void ); public: Rysunek(int X,int Y,int W,int H) : Fl_Widget(X,Y,W,H) {} }; int main() { Fl_Window window(300, 300, "Rysowanie"); Rysunek rysunek(0, 0, 300, 300); } window.end(); window.show(); return Fl::run();
Rysowanie - część II void Rysunek::draw( void ) { fl_color( 200, 0, 255 ); fl_point( 10, 10 ); fl_line( 20, 30, 100, 40 ); fl_color( FL_BLACK ); fl_line_style( FL_DASH, 3 ); fl_line( 50, 50, 100, 100 ); fl_line_style( FL_SOLID ); fl_rect( 200, 200, 20, 50 ); fl_rectf( 10, 200, 30, 20 ); fl_rectf( 50, 2, 30, 20, FL_GREEN ); } fl_color( FL_RED ); fl_arc(150, 150, 40, 50, 0, 360); fl_pie(150, 50, 80, 80, 0, 100);
Rysowanie
Wstawianie grafiki z pliku Klasy przechowujące grafikę ładowaną z pliku: Fl_GIF_Image Fl_JPEG_Image Fl_PNG_Image Fl_BMP_Image Fl_XPM_Image
Przykład - część I #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Draw.H> #include <FL/Fl_BMP_Image.H> class Rysunek : public Fl_Widget { void draw( void ); Fl_BMP_Image *bitmapa; public: Rysunek(int X,int Y,int W,int H) : Fl_Widget(X,Y,W,H) { bitmapa = new Fl_BMP_Image( "pingwin.bmp" ); } ~Rysunek() { delete bitmapa; } };
Przykład - część II void Rysunek::draw( void ) { bitmapa->draw( 10, 10 ); fl_color( FL_RED ); fl_line_style( FL_SOLID, 4 ); fl_arc( 85, 35, 40, 50, 0, 360); fl_arc( 123, 35, 40, 50, 0, 360); fl_line( 69, 38, 89, 45 ); fl_line( 179, 38, 159, 45 ); }
Przykład - część III int main() { Fl_Window window(243, 247, "Bitmapa"); Rysunek rysunek(0, 0, 243, 247); window.end(); window.show(); } return Fl::run();
Przykład - wynik