[wxWidgets] Elternframe informieren
-
Hallo,
skizze von meinem Programm:
class myframe : public wxFrame { myframe(); connect(); disconnect(); whendisconnet(); } class myclient : public wxSocketClient { connect(ip,port); disconnect(); onSocketEvent(); } myframe::myframe() { // Frame aufbauen // Connect zum Clienten connect(); } myframe::connect() { myclient.connect("192.168.0.61","1234"); } myframe::disconnect() { myclient.disconnect(); whendisconnet(); } myframe::whendisconnet() { // Tue alles was passieren muss wenn die Verbindung beendet wurde. } myclient.connect(ip,pot) { // Verbindung zum Server aufbauen // Eventhandler für Aktionen zu OnSocketEvent einrichten } myclient.onSocketEvent() { if (Verbindung_zum_server_verloren) { // Wie informiere ich ElternFrame oder ElternApp das die Verbindung weg ist??? } }
Das ist die Skizze meines Clienten. Ich habe die Netzwerkfunktionen vom Frame getrennt, weil ich diese immer und immer wieder in verschiedenen Programmen verwenden möchte. Das klappt auch ganz gut, nur habe ich das Problem, wenn der Server die Verbindung zum Clienten beendet, dann bekommt mein Client das nicht mit. Ich müsste in der Funktion myClient::onSocketEvent() eine Funktion von meiner "Mutter" aufrufen. In diesem Beispiel würde es die Funktion myframe::whendisconnet(); sein. In einem anderen Programm kann die Funktion aber ganz anders heissen.
Wie kann ich einer Klasse eine Funktion einer anderen Klasse nennen, die aufgerufen werden soll wenn ein bestimmter Falle eintritt?
Ich hab mich mal in Call-Back-Funktionen und Funktionszeigereingelesen. Alles was jedoch dabei hängen geblieben ist: Man kann nur static-Funktionen übergeben. Ich brauche allerdings eine Member-Funktion um ja auch z.B. meine Menüpunkte zu verändern und diese liegen als Zeiger in meiner Klasse.Danke für euere Hilfe,
Stefan
-
Man kann nicht nur statische Funktionen zurückrufen. Das klappt auch mit Klassen-Membern. Allerdings ist die Syntax dafür zugegebenermassen ziemlich... Naja, nicht gerade leicht im Kopf zu behalten, und ich bin zu Faul nachzusehen.
Ich würde dir boost::function<> (bzw. function aus dem neuen C++ Standard, falls dein Compiler das schon bereitstellt) empfehlen. In Verbindung mit boost::bind ist das extrem Flexibel und auch enigermassen Einfach.
Deinem Client übergibst du den Callback im Konstruktor, er speichert ihn in einem Member:
class myClient { boost::function<void()> callback; myClient (boost::function<void()> callback) : callback(callback) { } // ... void myFunktionThatNeedsToCallMyParent() { callback(); } }
Und dein Parent übergibt sie dann so:
new myClient(boost::bind(&myFrame::whendisconnet, this));
Die andere Möglichkeit wäre das Event-System von WX zu verwenden. Dann würde dein Client einfach ein Benutzerdefiniertes Event an seinen Vater posten.
-
Hallo,
ein Interessanter Ansatz mit Boost. Soweit ich aber verstanden habe muss ich dann innerhalb meiner Funktion ein neues Objekt erzeugen (myClient) wo ich dann die Funktion aufrufe. Ich kann aber kein neues Object brauchen, sondern benötige mein Original-Object, weil dort ja schon verschiedene Dinge initialisiert sind (z.B. Logger, Fenster, Menü, etc.)...
Ich werde mich wohl auf das WX-Event-System verlassen. Denn ich hab noch andere Dinge die ich an den Elternframe übergeben muss. Und per Liste kann ich dann die evrschiedenen Events übergeben. Mal schauen was es wird.
Danke für die Hilfe.
-
Du könntest auch eine Methode mit Parametern über boost::function aufrufen.
Alternativ kannst du es mit dynamic_cast und GetParent() versuchen, damit bekommst du einen Pointer auf dein aktuelles Parent.