[wxWidgets] Datenübergabe an wxEventHandler
-
Hallo,
Ich habe ein Problem, was ich zwar lösen kann, aber mir der Lösungsweg stark widerstrebt. In meinem Panel werden je nach Abhängigkeit der eingelesenen Daten eine gewisse Anzahl an Buttons erzeugt. Ich verbinde die Buttons mittels Connect mit dem Panel und rufe damit die Funktion auf. Diese hat ja als Parameter nur den EventHandler, ich kann also leider keine Identifikation mehr vornehmen, welcher Button gedrückt wurde (Vielleicht ginge es, wenn ich die ID's der Buttons weiter durchnummeriere, aber das einmal außen vor). Nun habe ich es so gehandhabt, dass ich dem Panel als Membervariablen (Array) die Daten mitgegeben habe und dann mittels den Membervariablen die Zuordnung zwischen dem gedrückten Button und der Information entsteht. Es hat auch seine Tücken, funktioniert aber an sich.
Ich kann mir aber nicht vorstellen, dass es keine Möglichkeit gibt, einen zusätzlichen Parameter der Funktion zu übergeben, welche den Event übernimmt? Da ich auf der Basis von lerning by doing arbeite, wäre es natürlich für meinen Programmierstil von Vorteil, wenn es dazu bessere Lösungen gibt.
Um Meine Frage auf den Punkt zu bringen: Kann ich der Funktion, welche mittels Buttonklick aufgerufen wird, Parameter irgendwie übergeben? Ich habe mir jetzt SetClientData angesehen, kann man das damit verwirklichen?
Liebe Grüße,
dioskur
-
Nein, da ist nur wxCommandEvent.
Du kannst aber dem Button eine ID geben, und über die ID dann den Button ermitteln.Oder dich fragen, ob es sein muss die Buttons dynamisch zu erzeugen.
Man könnte auch für jedes Element die Buttons auf ein eigenes Panel auslagern, welches dann das Handling übernimmt.phlox
-
Hallo und danke erstmal für die Antwort,
Leider müssen die Buttons dynamisch erzeugt werden. Es wird eine Matrix von Geometrien mit dazugehöriger Materialzusammensetzung erstellt und bei dem Material sollte man jede chemische Zusammensetzung ermöglichen.
Ich verstehe den Sinn hinter SetClientData an sich nicht. Gibt es dazu irgendwelche Beispiele? In dem Manual steht
Normally, any extra data the programmer wishes to associate with the object should be made available by deriving a new class with new data members. You must not call this method and SetClientObject on the same class - only one of them.
ich verstehe dann irgendwie den Nutzen nicht.
Das mit dem Panel hatte ich bisher auch so gelöst, dass ich eine Klasse davon abgeleitet hatte und in diese Klasse eine Membervariable geschrieben hatte, die die Daten beinhaltet hat. Über das Handling war es dann zugänglich.
Lieben Gruß,
dioskur
-
So, also mit SetClientData bekommt man was brauchbares hin.
zuerst vorm Aufruf:
R_Panel->SetClientData(this); R_Panel->Connect( ID_Add, wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PECS_Objekt::AddSurface));
void PECS_Objekt::AddSurface(wxCommandEvent &event) { wxArrayString *ptr_Parameter = NULL, *ptr_Parameter2 = NULL; PECS_Objekt *R_Class = NULL; ptr_Parameter = new wxArrayString(); ptr_Parameter2 = new wxArrayString(); R_Class = new PECS_Objekt(); [...] R_Class = (PECS_Objekt*) this->GetClientData(); // printf("pointer nach: %p \n",R_Class); (R_Class->m_Geometrie)->push_back(ptr_Parameter); (R_Class->m_Material)->push_back(ptr_Parameter2); }
-
R_Class = new PECS_Objekt(); [...] R_Class = (PECS_Objekt*) this->GetClientData();
Hoffe du gibst RClass vorher wieder frei
-
dioskur schrieb:
R_Panel->SetClientData(this); R_Panel->Connect( ID_Add, wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PECS_Objekt::AddSurface));
Warum nicht ? :
R_Panel->Connect( ID_Add, wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(PECS_Objekt::AddSurface), this);
Die wxDoku ist wirklich gut und immer einen Blick wert
-
Hallo!
Das Problem habe ich auch, verstehe aber leider eure Beispiele aber nicht.
Momentan versuche ich vor dem Connect mit "SetClientData" einen Integer zu setzen, den ich später auch gerne wieder bekommen würde, aber bei dem code hier unten gibt es einen error bei der "GetClientData"-Funktion.
Gibt es keine "Tag"-Funktion wie z.B. bei Borland?
Was ist der einfachste Weg die Nummer des geklickten Buttons herauszubekommen?
Die Buttons müssen dynamisch erstellt werden, abhängig von den Einträgen in einer ini-Datei. Alle rufen die selbe Funktion auf.void MyDialog::OnInit(wxInitDialogEvent& event) { //...mehr code... btnStart[i] = new wxButton(Panel1, wxID_ANY, _("Verbinden"), wxPoint(288,20+iAbstand*i), wxSize(72,23), 0, wxDefaultValidator, wxString::Format(wxT("btnVerbinden%2d"),i+1)); btnStart[i]->SetClientData(i); Connect(btnStart[i]->GetId(),wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&MyDialog::OnbtnVerbindenClick); //...mehr code... } void MyDialog::OnbtnVerbindenClick(wxCommandEvent& event) { int i; wxString aParameter; wxString para1,para2,para3,para4; i=(int)this->GetClientData(); //...mehr code... }
Könnt ihr mir weiterhelfen?
Gruß
-
Es würde mir auch ausreichen den Namen des geklickten Buttons herauszufinden.
Dann könnte ich mir daraus die Nummer holen, die sind durchnummeriert.Gibt es da irgendeine Methode?
Das oben genannte "this" bezieht sich doch auf das parent der Buttons, oder etwa nicht?
Gruß
-
Nein, this bezieht sich immer auf die aktuelle Klasse.
Die Id müsstest du evtl. auch direkt mit GetId() abfragen können.
-
Ich habe jetzt jedem einzelnen Button eine andere ID zugewiesen (100,101,102... usw).
Wie kann ich diese ID denn jetzt in meiner OnClick-Funktion (alle haben die selbe) auslesen, damit ich weiß welcher Button es war?
Einfach nur
i=GetId();
hilft da leider nicht, da kommt immer -202 raus.
Habt ihr eine Idee?
Edit:
Ich habs gefunden:i=event.GetId();
Danke an alle!