Programowanie graficznego interfejsu użytkownika Wykład 7 Maciej Wołoszyn mailto:woloszyn@fatcat.ftj.agh.edu.pl 26 kwietnia 2006 Spis treści 1 wxwidgets c.d. 1 1.1 Standardowe okna dialogowe.......................... 1 1.1.1 Wyświetlanie komunikatów...................... 2 1.1.2 Obsługa plików............................. 9 1.1.3 Wybór opcji............................... 11 1.1.4 Wprowadzanie danych......................... 14 1.2 Rysowanie i drukowanie............................ 14 1.2.1 Rysowanie przy użyciu wxclientdc.................. 15 1.2.2 Rysowanie przy użyciu wxpaintdc.................. 16 1.3 Obsługa zdarzeń związanych z myszą i klawiaturą............... 17 1.3.1 Mysz.................................. 17 1.3.2 Klawiatura............................... 18 1 wxwidgets c.d. 1.1 Standardowe okna dialogowe wyświetlanie lub pobieranie informacji za pomocą przygotowanych do tego celu okienek dialogowych: Proszę o przesyłanie na ten adres informacji o znalezionych błędach, literówkach oraz propozycji zmian i uzupełnień. Dokument przygotowano za pomocą systemu LATEX. Prawa autorskie zastrzeżone. 1
Programowanie GUI Wykład 7 2 minimalna ilość kodu spójny z resztą systemu wygląd i sposób obsługi 1.1.1 Wyświetlanie komunikatów wxmessagedialog informacja tekstowa (może również zawierać znaki nowej linii \n) tytuł okna z komunikatem przyciski (wybrane spośród OK, Cancel, Yes, No) style: wxok, wxcancel, wxyes_no pokaż przycisk odpowiednio: OK, Cancel, parę Yes/No wxyes_default jeśli użyte razem z wxyes_no powoduje, że Yes jest domyślnie wybrane (jest to ustawienie standardowe); wxno_default odwrotnie opcjonalnie grafika/ikona (np. wykrzyknik, pytajnik) style: wxicon_exclamation wxicon_error wxicon_question wxicon_information wyświetlenie następuje poprzez uruchomienie funkcji wxmessagedialog::showmodal rezultat jest kodem naciśniętego przez użytkownika przycisku: wxid_yes wxid_no wxid_ok wxid_cancel
Programowanie GUI Wykład 7 3 do tworzenia i wyświetlania okien opartych na klasie wxmessagedialog dostępna jest również wygodna funkcja wxmessagebox uwaga: zwraca inne wartości niż wxmessagedialog::showmodal, tzn. wxok, wxcancel, wxyes, wxno P01.cpp #include <wx/wx.h> class MyFrame: public wxframe { public: MyFrame(const wxstring& title); void OnButtonOK(wxCommandEvent& e); DECLARE_EVENT_TABLE() ; MyFrame::MyFrame(const wxstring& title) : wxframe(null, wxid_any, title) { wxbutton *b = new wxbutton(this,wxid_ok, "Start");
Programowanie GUI Wykład 7 4 void MyFrame::OnButtonOK( wxcommandevent& e) { wxmessagedialog d(this,"really\nstart?!", "Are you sure?",wxno_default wxyes_no wxicon_question); switch ( d.showmodal() ) { case wxid_yes : wxmessagebox("yes!"); break; case wxid_no : wxmessagebox("no!"); break; case wxid_cancel : //np. zamkn. okna! wxmessagebox("cancel!"); break; default : wxmessagebox("?!"); BEGIN_EVENT_TABLE(MyFrame, wxframe) EVT_BUTTON(wxID_OK, MyFrame::OnButtonOK) END_EVENT_TABLE() class MyApp: public wxapp { virtual bool OnInit(); ; bool MyApp::OnInit() { MyFrame *frame = new MyFrame( "P01"); frame->show(true); return true; IMPLEMENT_APP(MyApp)
Programowanie GUI Wykład 7 5 P02.cpp tylko jedna zmiana w porównaniu z P01.cpp: void MyFrame::OnButtonOK(wxCommandEvent& e){ if( wxok==wxmessagebox("continue","info", wxok wxcancel wxicon_exclamation) ) wxmessagebox("yes!");
Programowanie GUI Wykład 7 6 wxprogressdialog pasek postępu informacja tekstowa opcjonalnie czas działania/pozostały do końca operacji/szacowany całkowity style: wxpd_elapsed_time wxpd_estimated_time wxpd_remaining_time opcjonalnie przycisk Cancel styl wxpd_can_abort przy tworzeniu przekazuje się do konstruktora maksymalną wartość dla paska postępu (odpowiadającą 100%) można wymusić automatyczne ukrywanie okna po dojściu do maksimum (o likwidację obiektu musi zadbać program) styl wxpd_auto_hide oraz działanie jako okno modalne styl wxpd_app_modal po utworzeniu obiektu wxprogressdialog program kontynuuje działanie przy zablokowanym oknie macierzystym (lub wszystkich oknach aplikacji w przypadku użycia stylu modalnego) funkcja bool wxprogressdialog::update służy do zmiany wartości na pasku postępu i ew. treści komunikatu jeśli czasy są wyświetlane, będą obliczane automatycznie
Programowanie GUI Wykład 7 7 zwraca false jeśli użytkownik nacisnął Cancel; dopuszczalne jest kontynuacja działanie poprzez wywołanie wxprogressdialog::resume #include <wx/progdlg.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ const int max=100; wxprogressdialog d("wait", "Calculating", max, this, wxpd_can_abort wxpd_elapsed_time wxpd_estimated_time); for(int i=0; i<max; ++i) { if(! d.update(i)) break; wxsleep(1); wxbusyinfo nie jest okienkiem dialogowym, ale obszarem mogącym wyświetlać informację (np. Please wait... ) #include <wx/busyinfo.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ wxbusyinfo d("calculating...\naaaa",null); wxsleep(2);
Programowanie GUI Wykład 7 8 wxshowtip (funkcja) wyświetlanie porad/wskazówek przy starcie programu ( Czy wiesz, że... ) należy przekazać do tej funkcji obiekt wxtipprovider zawierający dane do wyświetlania; łatwo taki obiekt przygotować funkcją wxcreatefiletipprovider, której argumentami są nazwa pliku za wskazówkami (po jednej w linii) oraz numer pozycji do wyświetlenia #include <wx/tipdlg.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ wxtipprovider* t=wxcreatefiletipprovider( "data.txt", rand()%2); wxshowtip(this,t); data.txt (l.1) This function shows a "startup tip" to the user. (l.2) The return value is the state of the Show tips at startup checkbox.
Programowanie GUI Wykład 7 9 1.1.2 Obsługa plików wxfiledialog dostępne są wersję obsługujące wybór plików do odczytu oraz zapisu style wxsave, wxopen umożliwia wybór jednego lub wielu (styl wxmultiple) plików do odczytu można wymusić wybór wyłącznie istniejącego pliku (styl wxfile_must_exist) oraz ostrzeżenia o nadpisywaniu starej zawartości pliku (wxoverwrite_prompt) za pomocą argumentów konstruktora ustawić można: tytuł okna domyślny katalog (jeśli podany zostanie pusty napis okno dialogowe pokaże bieżący katalog) domyślną nazwę pliku maskę dla wyświetlanych plików, np. "BMP (*.bmp) *.bmp GIF (*.gif) *.gif" wyświetlenie następuje po wywołaniu funkcji wxfiledialog::showmodal, która zwróci wxid_ok jeśli użytkownik nacisnął OK lub wxid_cancel w przeciwnym wypadku informacje o dokonanych przez użytkownika wyborach uzyskuje się poprzez wywołania odpowiednich funkcji (zwracających wxstring), np.
Programowanie GUI Wykład 7 10 wxfiledialog::getdirectory wxfiledialog::getfilename wxfiledialog::getpath katalog + nazwa pliku void MyFrame::OnButtonOK(wxCommandEvent& e){ wxstring title = "Save file"; wxstring mask = "PNG (*.png) *.png GIF (*.gif) *.gif"; wxstring defdir = "/home/mw"; wxstring deffile = "plik.png"; wxfiledialog d(this, title, defdir, deffile, mask, wxsave); if(wxid_ok==d.showmodal()) { wxmessagebox("saving file"+d.getpath()); wxdirdialog wybór katalogu lokalnego lub sieciowego pozwala na tworzenie nowych katalogów jeśli włączony był styl wxdd_new_dir_button sposób uruchamiania i obsługi podobny jak dla wxfiledialog #include <wx/dirdlg.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ wxstring defdir = "/"; wxdirdialog d(this, "Choose dir.", defdir, wxdd_new_dir_button); if(wxid_ok==d.showmodal()) { wxmessagebox(d.getpath());
Programowanie GUI Wykład 7 11 1.1.3 Wybór opcji wxcolourdialog obsługuje dane o kolorach za pośrednictwem klasy wxcolourdata #include <wx/colordlg.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ wxcolourdata c; wxcolourdialog d(this, &c); if(wxid_ok==d.showmodal()) { /*...*/
Programowanie GUI Wykład 7 12 wxfontdialog wybór fontów i pobranie danych do obiektu klasy wxfontdata #include <wx/fontdlg.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ wxfontdata f; wxfontdialog d(this, &f); if(wxid_ok==d.showmodal()) { wxmessagebox("..."); wxsinglechoicedialog
Programowanie GUI Wykład 7 13 okienko dialogowe zawierające napisy umieszczone na liście wyboru oraz krótką informację do konstruktora należy przekazać obiekt klasy wxarraystring z danymi do wyświetlenia na liście wybrać można tylko jedną pozycję można sprawdzić numer wybranej pozycji funkcją wxsinglechoicedialog::getselection lub od razu pobrać wybrany tekst (wxstring) za pomocą wxsinglechoicedialog::getstringselection #include <wx/choicdlg.h> void MyFrame::OnButtonOK(wxCommandEvent& e){ wxarraystring t; t.add("aaa"); t.add("bbb"); t.add("ccc"); wxsinglechoicedialog d(this, "Test", "Choose one:",t); if(wxid_ok==d.showmodal()) { wxmessagebox(d.getstringselection()); wxmultichoicedialog
Programowanie GUI Wykład 7 14 podobny do wxsinglechoicedialog, ale pozwala na wybór dowolnej liczby pozycji funkcja wxmultichoicedialog::getselections zwraca obiekt wxarrayint zawierający numery wybranych pozycji 1.1.4 Wprowadzanie danych wxnumberentrydialog pobieranie wartości całkowitej z zadanego zakresu wxtextentrydialog pobieranie pojedynczej linii tekstu wpisany przez użytkownika tekst zwraca funkcja wxtextentrydialog::getvalue wxpasswordentrydialog pobranie hasła(zamaskowana linia tekstu); dziedziczy po wxtextentrydialog wxfindreplacedialog okno dialogowe przygotowane do obsługi wyszukiwania i zamiany tekstu nigdy nie jest oknem modalnym operacje wyszukiwania i ew. zamiany muszą być osobno zrealizowane i uruchamiane na skutel zdarzeń generowanych przez przyciski okna wxfindreplacedialog 1.2 Rysowanie i drukowanie rysowanie odbywa się zawsze przy użyciu kontekstu urzadzenia (Device Context) utworzonego dla okna, bitmapy, drukarki niektóre dostępne klasy pochodzące od wxdc wxclientdc do rysowania wewnątrz okna (ale poza zdarzeniami typu Paint Event) wxbuffereddc j.w., ale z podwójnym buforowaniem wxpaintdc do użycia gdy wystąpi Paint Event) wxbufferedpaintdc j.w., ale podwójne buf. wxmemorydc obsługa bitmap (rysowanie na bitmapie lub kopiowanie z bitmapy) wxprinterdc rysowanie na drukarkę
Programowanie GUI Wykład 7 15 klasa wxdc zapewnia zestaw funkcji do rysowania takich jak np. wxdc::setpen wxdc::setbrush wxdc::drawline wxdc::drawcircle 1.2.1 Rysowanie przy użyciu wxclientdc void MyFrame::OnDraw(wxCommandEvent& e) { wxclientdc dc(this); wxpen p(*wxred,3); dc.setpen(p); wxcoord w,h,x1,y1,x2,y2; dc.getsize(&w, &h); x1=rand()%w; x2=rand()%w; y1=rand()%h; y2=rand()%h; dc.drawline(x1,y1,x2,y2); wywołanie takiej funkcji (np. za pomocą połączonej z nią pozycji w menu) spowoduje każdorazowo wykreślenie linii obraz nie będzie odrysowywany gdy wystąpi Paint Event np. po zmianie wielkości okna (zawartość zniknie)
Programowanie GUI Wykład 7 16 1.2.2 Rysowanie przy użyciu wxpaintdc #include <wx/wx.h> class MyFrame: public wxframe { public: MyFrame(const wxstring& title); void OnPaint(wxPaintEvent& e); DECLARE_EVENT_TABLE() ; BEGIN_EVENT_TABLE(MyFrame, wxframe) EVT_PAINT(MyFrame::OnPaint) END_EVENT_TABLE() MyFrame::MyFrame(const wxstring& title) : wxframe(null, wxid_any, title) { void MyFrame::OnPaint(wxPaintEvent& e) { wxpaintdc dc(this); wxpen p(*wxred,3); dc.setpen(p); wxcoord w,h; dc.getsize(&w, &h); dc.drawrectangle(5,5,w-10,h-10); class MyApp: public wxapp { virtual bool OnInit(); ; bool MyApp::OnInit() { MyFrame *frame = new MyFrame("P16"); frame->show(true); return true; IMPLEMENT_APP(MyApp)
Programowanie GUI Wykład 7 17 1.3 Obsługa zdarzeń zwiazanych z mysza i klawiatura 1.3.1 Mysz informacja o zdarzeniu (np. naciśnięcie/zwolnienie przycisku, ruch) umieszczana jest w obiekcie typu wxmouseevent niektóre makra zdarzeń: EVT_LEFT_DOWN(funkcja) EVT_LEFT_UP(funkcja) EVT_LEFT_DCLICK(funkcja) analogicznie do powyższych dla środkowego (MIDDLE) i prawego (RIGHT) przycisku myszy EVT_MOTION(funkcja) EVT_MOUSE_EVENTS(funkcja) wszystkie zdarzenia szczegółowe informacje można uzyskać poprzez funkcje klasy wxmouseevent np. GetX(), GetY(), GetPosition() współrzędne zdarzenia ShiftDown() czy Shift był wciśnięty w czasie zdarzenia BEGIN_EVENT_TABLE(MyFrame, wxframe) EVT_LEFT_DOWN(MyFrame::OnMouse) END_EVENT_TABLE() void MyFrame::OnMouse(wxMouseEvent& e) {
Programowanie GUI Wykład 7 18 wxpoint pt(e.getposition()); wxclientdc dc(this); wxpen p(*wxred,3); dc.setpen(p); dc.drawrectangle(pt.x,pt.y,10,10); 1.3.2 Klawiatura trzy zasadnicze zdarzenia reprezentowane przez klasę wxkeyevent i odpowiadające im makra: naciśnięcie klawisza EVT_KEY_DOWN(funkcja) zwolnienie klawisza EVT_KEY_UP(funkcja) wpisanie znaku EVT_CHAR(funkcja) kod naciśniętego klawisza (np. WXK_HOME, WXK_LEFT, WXK_NUMPAD9, WXK_F1) można pobrać funkcją wxkeyevent::getkeycode