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,