In diesem Video zeige ich das Grundgerüst einer wxWidgets-Anwendung. Wir implementieren unsere eigene wxApp und schreiben die main-Funktion einmal via wx-Makro und einmal händisch.
Viel Spaß beim Implementieren.
Viele haben mir geschrieben, dass ich doch weitere Videos bzw. Tutorials machen soll. Das freut mich sehr.
Zur Zeit nimmt mich die neue Arbeitstelle und meine Familie gut ein, ich habe aber schon die nächsten Videos geplant (Themen: wxWidgets, Qt und auch FreeBSD) und freue mich, sie bald machen und veröffentlichen zu können. Es dauert allerdings noch ein paar Tage. Aber: Es wird mit den Tutorials weiter gehen.
Wenn ihr Vorschläge für bestimmte Themen habt, gerne her damit.
Eines meiner Projekte, dass ich vor wenigen Jahren gemacht hatte, lag noch auf meiner Festplatte und war bereits lange nicht mehr aktiv. Ich dachte mir allerdings, dass ich das noch einmal gerne als Referenz von mir online stellen wollte: compow.
Bei compow handelt es sich um eine Website, auf der sich Firmen vorstellen können und Stellenanzeigen schalten können. Ursprünglich war das mal kostenpflichtig, was ich aber herausgenommen habe, da ich nicht selbständig bin und damit kein Geld verdiene, es ist lediglich eine meiner Referenzen.
Das Interessante an der Website ist der Tech-Stack, denn anstelle einer der üblichen Webprogrammiersprachen wie Ruby, PHP, Python, Go, ASP.NET (keine Sprache, aber ihr wisst, was ich meine), basiert diese Website auf folgenden Technologien:
Wie gesagt, die Seite dient einfach nur als Referenz, womit ich mich in den letzten Jahren beschäftigte. Die Website ist nicht weiterentwickelt und wird es mitunter auch nicht.
Wer schnell und einfach wxWidgets auf Windows auf der Kommandozeile kompilieren will, öffnet ein Visual Studio Terminal, also ein Terminal, in dem die Umgebungsvariablen für VS gesetzt sind, navigiert zu den Sourcen von wxWidgets und dort ins Verzeichnis build\msw und kann via nmake den Kompilationsprozess in Gang setzen:
nmake /f makefile.vc BUILD=release SHARED=0 TARGET_CPU=X64 RUNTIME_LIBS=static
Wir sehen am Beispiel, dass wir eine Release-Version von wxWidgets bauen, also keine Debug-Informationen drin sind (ansonsten release einfach durch debug tauschen). SHARED=0 bedeutet, dass wir keine dynamischen Libraries bauen möchten (wenn doch, einfach weglassen). Die restlichen Parameter sollten ebenso selbsterklärend sein.
Um uns zu motivieren, schreiben wir in diesem Video unser erstes eigenes kleines Programm. Ihr könnt mal schauen, ob wxWidgets das Richtige für euch ist und schon, nach dem ersten Erfolgserlebnis, damit ein wenig herumspielen.
Und so sieht das Programm aus:
Hier noch der Quelltext:
#include <wx/wx.h>
class BruttoNettoApp : public wxApp {
public:
bool OnInit();
};
class BruttoNettoFrame : public wxFrame {
public:
BruttoNettoFrame();
private:
wxPanel *mainPanel;
wxBoxSizer *mainBoxSizer;
wxTextCtrl *priceTextCtrl;
wxStaticText *multiplicatorStaticText;
wxComboBox *taxComboBox;
wxButton *calculateButton;
wxTextCtrl *resultTextCtrl;
};
IMPLEMENT_APP(BruttoNettoApp)
bool BruttoNettoApp::OnInit() {
BruttoNettoFrame *bruttoNettoFrame = new BruttoNettoFrame;
bruttoNettoFrame->Show();
SetTopWindow(bruttoNettoFrame);
return true;
}
BruttoNettoFrame::BruttoNettoFrame() : wxFrame(nullptr, wxID_ANY, "Brutto-Netto-Rechner") {
mainPanel = new wxPanel(this, wxID_ANY);
mainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
priceTextCtrl = new wxTextCtrl(mainPanel, wxID_ANY);
mainBoxSizer->Add(priceTextCtrl, 1);
multiplicatorStaticText = new wxStaticText(mainPanel, wxID_ANY, "x");
mainBoxSizer->Add(multiplicatorStaticText);
taxComboBox = new wxComboBox(mainPanel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, 0, NULL, wxCB_READONLY);
taxComboBox->Append("7%");
taxComboBox->Append("19%");
taxComboBox->SetSelection(0);
mainBoxSizer->Add(taxComboBox);
calculateButton = new wxButton(mainPanel, wxID_ANY, "=");
calculateButton->Bind(wxEVT_BUTTON, [this](wxCommandEvent &event) {
double price = 0.f;
if(priceTextCtrl->GetValue().ToDouble(&price)) {
price *= taxComboBox->GetSelection() == 0 ? 1.07 : 1.19;
resultTextCtrl->SetValue(wxString::Format(_("%lf"), price));
} else {
wxMessageBox("Wrong price", "Error");
}
});
mainBoxSizer->Add(calculateButton);
resultTextCtrl = new wxTextCtrl(mainPanel, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
mainBoxSizer->Add(resultTextCtrl, 1);
mainPanel->SetSizer(mainBoxSizer);
mainBoxSizer->SetSizeHints(this);
SetSize(500, -1);
priceTextCtrl->SetFocus();
calculateButton->SetDefault();
}
Wer Windows und VisualStudio benutzt, kann auf den Play-Button klicken. Unter anderen Systemen könnte die Kompilierung so aussehen:
c++ NettoBruttoRechner.cpp -o NettoBruttoRechner -std=c++11 `wx-config --libs --cppflags`
Auf die einzelnen Komponenten gehe ich dann Stück für Stück in den nächsten Videos ein. Also keine Angst, falls Ihr hier etwas nicht verstehen solltet, das kommt bald.
Dieses Video zeigt, wie ihr einfach App-Bundles inklusive Icons für eure wxWidgets-Programme auf macOS erstellen könnt. Ebenfalls gehe ich auf den dylibbundler ein, um ein einfache Deployment durchzuführen.
Hier noch die Dateien:
Info.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key> <string>English</string>
<key>CFBundleExecutable</key> <string>wx</string>
<key>CFBundleInfoDictionaryVersion</key> <string>6.0</string>
<key>CFBundlePackageType</key> <string>APPL</string>
<key>CSResourcesFileMapped</key> <true/>
<key>CFBundleVersion</key> <string>0.0.1</string>
<key>CFBundleShortVersionString</key> <string>0.0.1</string>
<key>CFBundleName</key> <string>My wxApp</string>
<key>CFBundleIconFile</key> <string>AppIcon</string>
</dict>
</plist>
Script zum Kompilieren
#!/bin/sh
PROGRAM="wx"
BUNDLE="wx.app"
ICON="AppIcon.icns"
test -d "${BUNDLE}" && rm -Rf "${BUNDLE}"
c++ *.cpp -o wx -std=c++11 `/usr/local/Cellar/wxWidgets/3.2.1/bin/wx-config --libs --cppflags`
if [ $? == 0 ]
then
mkdir -p "${BUNDLE}/Contents/MacOS"
echo -n 'APPL????' > "${BUNDLE}/Contents/PkgInfo"
mv "${PROGRAM}" "${BUNDLE}/Contents/MacOS/"
cp "Info.plist" "${BUNDLE}/Contents/"
mkdir -p "${BUNDLE}/Contents/Resources"
cp "${ICON}" "${BUNDLE}/Contents/Resources/"
mkdir "${BUNDLE}/Contents/lib" && ln -s "${BUNDLE}/Contents/lib" "${BUNDLE}/Contents/libs"
/usr/local/Cellar/dylibbundler/1.0.4/bin/dylibbundler -od -b -x "${BUNDLE}/Contents/MacOS/${PROGRAM}" -d "${BUNDLE}/Contents/lib"
fi
Programmcode
#include <wx/wx.h>
class MyApp : public wxApp {
public:
bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() {
MyFrame *myFrame = new MyFrame;
myFrame->Show();
SetTopWindow(myFrame);
return true;
}
MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "Meine wx-App") {
wxStaticText *staticText = new wxStaticText(this, wxID_ANY, "Hello World");
}
In diesem Video zeige ich, wie man wxWidgets mit Hilfe von Homebrew auf macOS installieren kann.
Eine kurze Zusammenfassung:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install wxwidgets
brew install dylibbundler
So sieht es dann aus:
Hier noch der Programmcode zum Testen:
#include <wx/wx.h>
class MyApp : public wxApp {
public:
bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() {
MyFrame *myFrame = new MyFrame;
myFrame->Show();
SetTopWindow(myFrame);
return true;
}
MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "Meine wx-App") {
wxStaticText *staticText = new wxStaticText(this, wxID_ANY, "Hello World");
}
Kompiliert wird das ganze via:
c++ *.cpp -o mywxapp -std=c++11 `/usr/local/Cellar/wxwidgets/3.2.0_1/bin/wx-config --libs --cppflags`
Wer wxWidgets auf macOS selbst kompilieren möchte, findet hier eine Anleitung.
Dieses Video zeigt, wie einfach die Installation von wxWidgets unter FreeBSD geht.
wxWidgets ist einfach installierbar:
pkg install wx31-gtk3
Hier das Beispielprogramm:
#include <wx/wx.h>
class MyApp : public wxApp {
public:
bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() {
MyFrame *myFrame = new MyFrame;
myFrame->Show();
SetTopWindow(myFrame);
return true;
}
MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "Meine wx-App") {
wxStaticText *staticText = new wxStaticText(this, wxID_ANY, "Hello World");
}
Und so wird es kompiliert:
c++ *.cpp -o mywxapp `wxgtk3u-3.1-config --libs --cppflags` -std=c++11
Folgendermaßen sieht es dann aus:
In diesem Video zeige ich, wie man wxWidgets unter Linux, in unserem Szenario Ubuntu, installieren kann.
Installiert werden kann wxWidgets folgendermaßen:
sudo apt install libwxgtk3.0-gtk3-dev
Hier der Quellcode von unserer Test-Anwendung:
#include <wx/wx.h>
class MyApp : public wxApp {
public:
bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() {
MyFrame *myFrame = new MyFrame;
myFrame->Show();
SetTopWindow(myFrame);
return true;
}
MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "Meine wx-App") {
wxStaticText *staticText = new wxStaticText(this, wxID_ANY, "Hello World");
}
Und so wird es kompiliert:
c++ mywxapp.cpp -o mywxapp `wx-config --libs --cppflags` -std=c++11
Danach sieht es in etwa so aus:
Dieses Video zeigt, wie man wxWidgets selbst auf Windows mit Hilfe von Visual Studio (nicht Visual Studio Code) kompilieren und benutzen kann.
Zuerst muss das wxWidgets.zip für Windows heruntergeladen werden. Unter build öffnet man dann die zum installierten Visual Studio passende Projektdatei. Dann kompliert man (Projektmappe erstellen) für mindestens folgende Plattformen:
In den Projekteinstellugen des eigenen Projekts stellt man die Konfiguration für Plattform und Modus auf Alle. Dann fügt man die Include-Verzeichnisse (include und include/msvc) hinzu. Unter System wird von Console auf Windows umgestellt. Abschließend wählt man Win32 aus und fügt den entsprechenden Bibliothekspfad hinzu. Das selbe mit x64.
Ich zeige das genau in dem Video.
Hier noch der Quelltext unserer Testanwendung:
#include <wx/wx.h>
class MyApp : public wxApp {
public:
bool OnInit();
};
class MyFrame : public wxFrame {
public:
MyFrame();
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit() {
MyFrame *myFrame = new MyFrame;
myFrame->Show();
SetTopWindow(myFrame);
return true;
}
MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "Meine wx-App") {
wxStaticText *staticText = new wxStaticText(this, wxID_ANY, "Hello World");
}
So sieht es dann aus:
Wer nicht Visual Studio benutzen möchte, kann hier einmal nachsehen, wie man wxWidgets ohne Visual Studio kompiliert.