Programowanie GUI
Transkrypt
Programowanie GUI
Programowanie graficznego interfejsu użytkownika Wykład 7 Maciej Wołoszyn mailto:[email protected]∗ 26 kwietnia 2006 Spis treści 1 wxWidgets c.d. 1.1 1.2 1.3 1 Standardowe okna dialogowe . . . . . . . . . . . . 1.1.1 Wyświetlanie komunikatów . . . . . . . . 1.1.2 Obsługa plików . . . . . . . . . . . . . . . 1.1.3 Wybór opcji . . . . . . . . . . . . . . . . . 1.1.4 Wprowadzanie danych . . . . . . . . . . . Rysowanie i drukowanie . . . . . . . . . . . . . . 1.2.1 Rysowanie przy użyciu wxClientDC . . . . 1.2.2 Rysowanie przy użyciu wxPaintDC . . . . Obsługa zdarzeń zwiazanych ˛ z mysza˛ i klawiatura˛ . 1.3.1 Mysz . . . . . . . . . . . . . . . . . . . . 1.3.2 Klawiatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 2 9 11 14 14 15 16 17 17 18 1 wxWidgets c.d. 1.1 Standardowe okna dialogowe • wyświetlanie lub pobieranie informacji za pomoca˛ przygotowanych do tego celu okienek dialogowych: ∗ Prosz˛ e o przesyłanie na ten adres informacji o znalezionych bł˛edach, literówkach oraz propozycji zmian i uzupełnień. Dokument przygotowano za pomoca˛ systemu LATEX. Prawa autorskie zastrzeżone. 1 Programowanie GUI – Wykład 7 2 – minimalna ilość kodu – spójny z reszta˛ systemu wyglad ˛ 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˛e 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˛epuje poprzez uruchomienie funkcji wxMessageDialog::ShowModal → rezultat jest kodem naciśni˛etego 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˛epna jest również wygodna funkcja wxMessageBox uwaga: zwraca inne wartości niż wxMessageDialog::ShowModal, tzn. wxOK, wxCANCEL, wxYES, wxNO 5 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 } 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) 4 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!"); } 5 Programowanie GUI – Wykład 7 6 wxProgressDialog • pasek post˛epu • 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˛e do konstruktora maksymalna˛ wartość dla paska post˛epu (odpowiadajac ˛ a˛ 100%) • można wymusić automatyczne ukrywanie okna po dojściu do maksimum (o likwidacj˛e 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˛epu i ew. treści komunikatu – jeśli czasy sa˛ wyświetlane, b˛eda˛ obliczane automatycznie Programowanie GUI – Wykład 7 7 ˛ Cancel; dopuszczalne jest kontynuacja – zwraca false jeśli użytkownik nacisnał 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 mogacym ˛ wyświetlać informacj˛e (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 zawierajacy ˛ dane do wyświetlania; łatwo taki obiekt przygotować funkcja˛ wxCreateFileTipProvider, której argumentami sa˛ 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); } 5 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˛epne sa˛ wersj˛e obsługujace ˛ 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łacznie ˛ istniejacego ˛ pliku (styl wxFILE_MUST_EXIST) oraz ostrzeżenia o nadpisywaniu starej zawartości pliku (wxOVERWRITE_PROMPT) • za pomoca˛ argumentów konstruktora ustawić można: – tytuł okna – domyślny katalog (jeśli podany zostanie pusty napis okno dialogowe pokaże bieżacy ˛ katalog) – domyślna˛ nazw˛e pliku – mask˛e dla wyświetlanych plików, np. "BMP (*.bmp)|*.bmp|GIF (*.gif)|*.gif" • wyświetlenie nast˛epuje po wywołaniu funkcji wxFileDialog::ShowModal, która zwróci wxID_OK jeśli użytkownik nacisnał ˛ OK lub wxID_CANCEL w przeciwnym wypadku • informacje o dokonanych przez użytkownika wyborach uzyskuje si˛e poprzez wywołania odpowiednich funkcji (zwracajacych ˛ 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łaczony ˛ 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 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()) { /*...*/ } } 11 Programowanie GUI – Wykład 7 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 12 Programowanie GUI – Wykład 7 13 • okienko dialogowe zawierajace ˛ napisy umieszczone na liście wyboru oraz krótka˛ informacj˛e • do konstruktora należy przekazać obiekt klasy wxArrayString z danymi do wyświetlenia na liście • wybrać można tylko jedna˛ pozycj˛e • można sprawdzić numer wybranej pozycji funkcja˛ wxSingleChoiceDialog::GetSelection lub od razu pobrać wybrany tekst (wxString) za pomoca˛ 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 zawierajacy ˛ 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 musza˛ być osobno zrealizowane i uruchamiane na skutel zdarzeń generowanych przez przyciski okna wxFindReplaceDialog 1.2 Rysowanie i drukowanie • rysowanie odbywa si˛e zawsze przy użyciu kontekstu urzadzenia ˛ (Device Context) utworzonego dla okna, bitmapy, drukarki • niektóre dost˛epne klasy pochodzace ˛ od wxDC – wxClientDC – do rysowania wewnatrz ˛ okna (ale poza zdarzeniami typu Paint Event) – wxBufferedDC – j.w., ale z podwójnym buforowaniem – wxPaintDC – do użycia gdy wystapi ˛ Paint Event) – wxBufferedPaintDC – j.w., ale podwójne buf. – wxMemoryDC – obsługa bitmap (rysowanie na bitmapie lub kopiowanie z bitmapy) – wxPrinterDC – „rysowanie” na drukark˛e 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 pomoca˛ połaczonej ˛ z nia˛ pozycji w menu) spowoduje każdorazowo wykreślenie linii • obraz nie b˛edzie odrysowywany gdy wystapi ˛ Paint Event – np. po zmianie wielkości okna (zawartość zniknie) Programowanie GUI – Wykład 7 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) 16 Programowanie GUI – Wykład 7 17 ˛ z mysza˛ i klawiatura˛ 1.3 Obsługa zdarzeń zwiazanych 1.3.1 Mysz • informacja o zdarzeniu (np. naciśni˛ecie/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˛edne zdarzenia – ShiftDown() – czy Shift był wciśni˛ety 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˛e wxKeyEvent i odpowiadajace ˛ im makra: – naciśni˛ecie klawisza – EVT_KEY_DOWN(funkcja) – zwolnienie klawisza – EVT_KEY_UP(funkcja) – wpisanie znaku – EVT_CHAR(funkcja) – kod naciśni˛etego klawisza (np. WXK_F1) można pobrać funkcja˛ wxKeyEvent::GetKeyCode WXK_HOME, WXK_LEFT, WXK_NUMPAD9,