PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : wxWindows Tutorial



oracle2025
22-10-2003, 20:17
Was ist wxWindows

wxWindows ist ein sogenanntes Widgetset, ähnlich wie z.B. Qt oder GTK+, anders als die eben genannten hat wxWindows allerdings kein festgelegtes "Look and Feel", sondern passt sich an die jeweilige Plattform an auf der es läuft. So ist ein wxWindows Programm das für MS Windows kompiliert wurde nicht von einem "richtigen" Windows-Programm zu unterscheiden. Ebenso verhält es sich wenn man wxWindows unter MacOSX nutzt. Unter Linux nimmt wxWindows meist den GTK+ Look an, und zwar wahlweise GTK-2 oder GTK-1.2.

Programmiert wird wxWindows in C++, für andere Programmiersprachen stehen allerdings auch Anbindungen bereit. Besonders hervorzuheben ist hier die Python-Version, sie ermöglicht es auf einfachste Weise vollständig plattformunabhängige Programme mit professionell aussehender Grafischer Oberfläche zu erstellen.

Installation

In gängigen Linux-Distributionen ist wxWindows meist nicht installiert, man muss es von http://www.wxwindows.org/ herunterladen. Entscheidet man sich wxWindows aus den Sourcen zu kompilieren empfiehlt es sich beim ./configure die schalter --enable-gtk2 und --enable-unicode anzugeben. Dadurch werden die wxWindows-Programme dann mit dem modernen "Look and Feel" von GTK2 ausgestattet sein.

Möchte man wxWindows unter MS Windows nutzen, kann man beispielsweise den freien MinGW Kompiler nutzen, der auf http://www.mingw.org/ zu haben ist. Neben dem MinGW-Paket sollte man sich auch noch das MSYS-Paket herunterladen, das etliche zusätzlich Entwicklungswerkzeuge enthält. wxWindows erhält man anschliessend von http://www.wxwindows.org/. In der MSYS-Shell läßt es sich dann wie gewohnt mit ./configure und make kompilieren.

Für MacOSX werden die Appel Developer-Tools benötigt, die dem Betriebsystem beiligen. Alles weitere findet sich dann wieder auf der wxWindows Homepage.

Hello World


#include "wx/wx.h"
class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style = wxDEFAULT_FRAME_STYLE);
void OnHello(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE()
};
enum
{
ID_HelloButton = 1,
ID_Button2,
ID_Button3
};
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(ID_HelloButton, MyFrame::OnHello)
END_EVENT_TABLE()

MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
: wxFrame(NULL, -1, title, pos, size, style)
{
wxPanel *panel1 = new wxPanel(this,-1);
wxButton *helloButton = new wxButton(panel1,ID_HelloButton,wxT("Hello"),wxPoint(30,30));

wxBoxSizer *frameSizer = new wxBoxSizer(wxVERTICAL);
frameSizer->Add(panel1,1,wxEXPAND);
this->SetSizer(frameSizer);
}
void MyFrame::OnHello(wxCommandEvent& WXUNUSED(event))
{
puts("World");
}

class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame(wxT("wxWindows Hello World"),
wxPoint(50, 50), wxSize(450, 340) );
frame->Show(TRUE);
return TRUE;
}


Das Ganze speichern wir in eine Datei mit dem Namen "hello.c" und kompilieren es unter Linux mit folgender Befehlszeile unter Linux.



g++ `wx-config --libs --cxxflags` hello.cpp -o hello


Sollte alles geklappt haben sieht man nach dem Starten des Hello Programs ein Fenster mit einem Knopf auf dem Bildschirm. Wie ist dieses nun zustande gekommen?

Gehen wir also etwas ins Detail.

Am Begin der Datei wird als erstes der wxWindows-Header #include "wx/wx.h" eingebunden. Was das bedeutet sollte wohl jedem klar sein ;) .

Das Äquivalent zur Main Funktion ist in wxWindows etwas komplizierter, und im folgenden enthalten:


class MyApp : public wxApp
{
public:
virtual bool OnInit();
};
IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
/* ----- */
return TRUE;
}

Es wird eine Unterklasse von wxApp erzeugt, in dieser die Funktion OnInit() überschrieben, und das Makro IMPLEMENT_APP(MyApp) aufgerufen. Das alles ist nötig damit wxWindows intern irgendwelchen "Magic-Code" initialisieren kann.

Der eigentlich Einstieg ins Programm ist die Funktion OnInit(). Sie entspricht sozusagen der main() Funktion eines normalen C++ Programms, und wird aus Sicht des Entwicklers als erstes ausgeführt.



MyFrame *frame = new MyFrame(wxT("wxWindows Hello World"),
wxPoint(50, 50), wxSize(450, 340) );
frame->Show(TRUE);


Dieses Stückchen Code dürfte auch selbsterklärend sein, es wird ein Klasse vom Typ MyFrame erzeugt, die von der Klasse wxFrame abstammt, aber dazu später mehr. Der erste Parameter ist der Titel des Fensters, der Zweite die Position, und der Dritte gibt die Größe an.
Ungewohnt dürfte hingegen das wxT() sein, das den String umschliesst. Dieses ist nur dann nötig, wenn man wxWindows um Unicode-Modus nutzt, und sorgt dafür, das der Text in das richtige Zeichenformat umgewandelt wird.

Die Klasse wxFrame repräsentiert ein Fenster, und das Erzeugen einer Unterklasse ist die bevorzugte Möglichkeit ein ebensolches mit eigenen Vorstellungen und Ideen zu füllen.



class MyFrame : public wxFrame
{
public:
MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style = wxDEFAULT_FRAME_STYLE);
void OnHello(wxCommandEvent& event);
private:
DECLARE_EVENT_TABLE()
};


Wir werden ein Fenster bauen, das nur einen einzigen Knopf enthält, und deswegen erhält unsere Klasse im Moment auch nur eine einzige Funktion, die aufgerufen werden soll, sobald der Knopf gedrückt wird. Sie heißt OnHello.

Der Begriff DECLARE_EVENT_TABLE() sorgt dafür das beim Kompilieren die nötige Funktionalität für das Eventhandling in die Klasse eingebaut wird, sprich das der Druck auf den Button auch tatsächlich die dazugehörige Funktion aufruft.



enum
{
ID_HelloButton = 1,
ID_Button2,
ID_Button3
};


Jedes grafische Element innerhalb eines wxWindows Fensters sollte mit einer eindeutigen Id gekennzeichnet sein, damit später im Programm z.B. der dritte Knopf nicht versehentlich die Funktion des Ersten aufruft. Dies erreichen wir durch das enum Feld, in das wir einfach für jedes Element der GUI eine Id einfügen.



BEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_BUTTON(ID_HelloButton, MyFrame::OnHello)
END_EVENT_TABLE()


Das ist die sogenannte Eventtabelle, in dieser wird festgelegt, welcher Knopf den nun wirklich für welche Funktion verantwortlich ist. In der ersten Zeile geben wir den Namen unserer Klasse an, sowie den Namen der Basisklasse.
Anschliessend verbinden wir einen Button Event der von der Id ID_HelloButton gesendet wird mit der Funktion OnHello der Klasse MyFrame. Ganz einfach oder?


MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, long style)
: wxFrame(NULL, -1, title, pos, size, style)
{
wxPanel *panel1 = new wxPanel(this,-1);
wxButton *helloButton = new wxButton(panel1,ID_HelloButton,wxT("Hello"),wxPoint(30,30));

wxBoxSizer *frameSizer = new wxBoxSizer(wxVERTICAL);
frameSizer->Add(panel1,1,wxEXPAND);
this->SetSizer(frameSizer);
}


Das ist der Konstruktor unserer Frame-Klasse, er ruft den Konstruktor der Basis-Klasse auf, und erzeugt die Grafische Oberfläche.
Als erstes Element wird ein wxPanel erzeugt, das die Id -1 erhält. Das bedeutet, soviel wie "Events die dieses Element aussendet interessieren niemanden".

Und in das Panel wird dann unser Hello-Button eingefügt. Wir könnten den Button auch direkt in den Frame setzen, allerdings ist der Hintergrund eines Frames unter MS Windows etwas dunkler, und das Panel sorgt dafür das das Programm die richtige Farbe im Hintergrund hat.

Schliesslich wird der Button erzeugt, er erhält seine Id, eine Beschriftung, und die Position an der zu sein hat.

Damit sich bei einer Größenänderung des Frames das Panel anpasst, wird es am Ende noch in einen sogenannten "Sizer" eingefügt.



void MyFrame::OnHello(wxCommandEvent& WXUNUSED(event))
{
puts("World");
}


und hier noch der Schluss, dies ist die Funktion die beim Druck auf den Knopf aufgerufen wird, sie gibt auf der Konsole das Wort "World" aus.

Links
Wer mehr über wxWindows wissen will, dem kann ich nur zur sehr ausführlichen wxWindows Referenz raten, einige Tipps finden sich auch auf http://wxguide.sourceforge.net/.
http://www.wxpython.org/ enthält die Python Bindings für wxWindows, und wer einen Programm zum erstellen von Grafischen Oberflächen sucht, findet es auf http://www.roebling.de/ mit 29€ für die Studenten-Version ist es eigentlich recht günstig.

Fehler, Verbesserungs-Verschläge, unter Feedback jeglicher Art und Weise bitte per PM an mich.

mit freundlichen Grüßen
Richard Spindler