Grafiske Brukergrensesnitt (GUI)
Grafiske brukergrensesnitt
Konstruksjon av grafiske grensesnitt
Grafiske grensesnitt består av en rekke GUI elementer som kalles widgets
. Dette kan være knapper, tekstfelt eller dropdown lister.
Callback
Et «callback» er en funksjon som kalles etter en spesifikk hendelse har inntruffet. Disse brukes ofte med brukergrensesnitt, for eksempel for å spesifisere hva som skal skje etter brukeren har trykket på en knapp. Hvert GUI-element lar deg definere én slik funksjon som blir kjørt etter hver interaksjon. Nøyaktig hvilken interaksjon er avhengig av GUI-elementet.
For å vise hvordan man definerer og bruker en callback funksjon, fortsetter vi med samme eksempelet som før:
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/Button.h"
int main()
{
const Point buttonPosition {100, 100};
const unsigned int buttonWidth = 100;
const unsigned int buttonHeight = 40;
const string buttonLabel = "Click me!";
Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel};
AnimationWindow window;
window.add(button);
window.wait_for_close();
return 0;
}
Vi kan nå definere callback funksjonen. Den skal ha ingen parametere, og returnere void
. Det er mulig å definere flere callback funksjoner i en enkelt fil, og navnet på funksjonene er ikke viktig. Flere GUI elementer kan ha samme callback funksjonen.
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/Button.h"
void callbackFunction() {
std::cout << "This is printed when this function is executed." << std::endl;
}
int main()
{
const Point buttonPosition {100, 100};
const unsigned int buttonWidth = 100;
const unsigned int buttonHeight = 40;
const string buttonLabel = "Click me!";
Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel};
AnimationWindow window;
window.add(button);
window.wait_for_close();
return 0;
}
Den siste steget er å bruke callbackFunction()
funksjonen som callback av knappen vi laget tidligere. Vi gjør dette ved å bruke setCallback()
funksjonen, med navn på funksjonen som vi ønsker å bruke som parameter:
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/Button.h"
void callbackFunction() {
std::cout << "This is printed when this function is executed." << std::endl;
}
int main()
{
const Point buttonPosition {100, 100};
const unsigned int buttonWidth = 100;
const unsigned int buttonHeight = 40;
const string buttonLabel = "Click me!";
Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel};
AnimationWindow window;
button.setCallback(callbackFunction);
window.add(button);
window.wait_for_close();
return 0;
}
Når vi kjører dette programmet og klikker på knappen ser vi at callback funksjonen skriver ut tekst på skjermen:
Objekt-orienterte callback funksjoner
Dersom man ønsker å sette callback-funksjonen til en klassemetode må man bruke std::bind
for å gjøre funksjonen kompatibel.
class SuperManWindow : public AnimationWindow {
public:
SuperManWindow();
void superCallbackFunction();
void fly();
private:
Button flyButton;
};
void SuperManWindow::superCallbackFunction() {
std::cout << "Thanks for clicking, im going to fly\n";
this->fly();
// Do something else
}
SuperManWindow::SuperManWindow()
: AnimationWindow(50, 50, 500, 500, "Super man window"),
flyButton{{100, 100}, 50, 50, "fly"} {
// Here we convert the class method to a void function
// by binding this instance of the class to the function
flyButton.setCallback(std::bind(&SuperManWindow::superCallbackFunction, this));
add(flyButton);
}
GUI Elementer
Hvert GUI element som kan brukes i en AnimationWindow er definert i sin egen klasse. Det vil si at når du for eksempel ønsker å vise en knapp i vinduet, lager du en instans av TDT4102::Button
klassen. I tillegg er det nødvendig å legge til knappen i vinduet ved å bruke medlemsfunksjonen:
Alle GUI elementer arver fra typen Widget
. Widget
har en funksjon for å gjemme eller vise GUI elementene:
true
for å vise elementet og med false
for å skjule elementet.
Knapp
En knapp er et GUI element som gjør noe når du klikker på den:
Her er et eksempel som vises hvordan den brukes:
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/Button.h"
void buttonClicked() {
std::cout << "Someone clicked on me!" << std::endl;
}
int main()
{
const Point buttonPosition {100, 100};
const unsigned int buttonWidth = 100;
const unsigned int buttonHeight = 40;
const string buttonLabel = "Click me!";
Button button {buttonPosition, buttonWidth, buttonHeight, buttonLabel};
AnimationWindow window;
window.add(button);
button.setCallback(buttonClicked);
button.setButtonColor(Color::silver);
window.wait_for_close();
return 0;
}
Merk at vi må først inkludere headeren til TDT4102::Button
klassen ved å skrive #include "widgets/Button.h"
øverst i filen.
Deretter lager vi en knapp ved å instansiere TDT4102::Button
klassen, som har følgende konstruktøren:
Her definerer TDT4102::Point location
hvor knappen skal plasseres på skjermen, width
og height
størrelsen, og label
teksten som skal vises på knappen. Vi bruker add()
og setCallback()
funksjonene å sørge for at knappen blir synlig i vinduet, og at det skjer noe når vi klikker på den.
Callback funksjonen blir kalt hver gang brukeren klikker på knappen.
Buttonklassen har diverse funksjoner for å endre på utseende.
void setLabel(std::string newLabel);
void setLabelColor(Color newColor);
void setButtonColor(Color newColor);
void setButtonColorHover(Color newColor);
void setButtonColorActive(Color newColor);
Du kan endre tekst og tekstfarge med setLabel
og setLabelColor
. Du kan endre fargen for knappen med setButtonColor
, fargen når du har musen over med setButtonColorHover
og fargen på knappen når den er trykket ned med setButtonColorActive
.
Tekst felt
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/TextInput.h"
TextInput textField {{100, 100}, 300, 30, "This text field is small!"};
void textFieldChanged() {
std::cout << "The text field now contains: " << textField.getText() << std::endl;
}
int main()
{
AnimationWindow window;
window.add(textField);
textField.setCallback(textFieldChanged);
window.wait_for_close();
return 0;
}
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/TextInput.h"
TextInput textField {{100, 100}, 300, 150, "This text field\ncontains more than\none line of text!"};
void textFieldChanged() {
std::cout << "The text field now contains: " << textField.getText() << std::endl;
}
int main()
{
AnimationWindow window;
window.add(textField);
textField.setCallback(textFieldChanged);
window.wait_for_close();
return 0;
}
Dropdown list
#include "std_lib_facilities.h"
#include "AnimationWindow.h"
#include "widgets/DropdownList.h"
std::vector<std::string> options {"Hello", "There", "General", "You", "Are", "A", "Bold", "One"};
DropdownList list({100, 100}, 300, 30, options);
void handle() {
std::cout << "Selected: " << list.getValue() << std::endl;
}
int main()
{
AnimationWindow window;
window.add(list);
list.setCallback(handle);
window.wait_for_close();
return 0;
}