GELÖST: ostream einer Funktion bekannt machen um nach TextCtrl zu schreiben
-
Hallo Forum,
ich habe momentan ein kleines Frame, indem befindet ein wxTextCtrl und zwei Buttons.
Der Klick auf einen Button ruft eine Funktion auf, die eine Kommunikation über die serielle Schnittstelle mit einem µC durchführen soll...
Die Kommunikation klappt "1A" innerhalb einer Konsolenanwendung, also da liegt der Fehler schonmal nicht.
Aber erstmal weiter, das TextCtrl-Widget heißt "text" und es soll der Ausgabestream nach Text umgeleitet werden, das mache ich hiermit:
ostream stream(text);
So, ostream lässt sich aber nur in der Funktion wo text schon definiert ist (im Header, nach Deklaration geht das nicht) anlegen, ansonsten erhalte ich auch eine Fehlermeldung...
Jetzt ist natürlich das Problem, wie kann ich dem Button/ der Funktion stream bekannt machen? Vom Button auf die Funktion geht ja noch. Aber wie lernt der Button den stream kennen?
Als EventHandler benutze ich:
Connect(ID_CON, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxWCK::OnClickCon));
Bin für jeden Vorschlag dankbar.
Ich hoffe mein Problem konnte ich gut beschreiben, ansonsten fragt nochmal genauer nach.
-Nod
Ganz vergessen:
OS: Win8.1 | Compiler: G++ | IDE: CodeLite 5.1 | wxWidget: 2.9
-
Ok, ich will meine Frage nochmal konkretisieren, eventuell wird es für euch damit etwas klarer.
Ich definiere in meinen Frame einen ostream, dieser soll mit dem EventHandler zu der EventHandleFunction übertragen werden.
Wie kann ich das machen?
Etwas wie eine Funktion: "GetVariable(*parent)" wäre sehr nützlich. Leider ist mir weder für Cpp noch wxWidgets so eine Funktion bekannt. (Bitte klärt mich auf falls es diese gibt, Google hat leider auch nichts ausgespuckt und weder der "C++-Primer" noch die wxW-Doku haben eine Funktion mit dem Namen hinterlegt.
Ein Workaround was mir noch eingefallen ist, ich aber für ziemlich unelegant halte: Ich definiere einfach eine "Work"-Datei und lasse den Stream wie folgt laufen:
Funktion >> Datei >> TextCtrl
-
Wiso dem eventhanlder mitgeben, der Handler ist anscheinend in einer klasse implementiert, wiso gibst du dieser klasse nicht einfach den ostream beim erzeugen der instanz mit?
-
So, ostream lässt sich aber nur in der Funktion wo text schon definiert ist (im Header, nach Deklaration geht das nicht) anlegen, ansonsten erhalte ich auch eine Fehlermeldung...
Wenn ich ostream in der Klasse deklariere und normal verwenden will erhalte ich die Fehlermeldung das er die "Funktion" nicht kennt und ob ich eventuell das '()' vergessen hätte...
Ich häng jetzt fast schon einen Tag lang an dem Problem (und einem anderen), da hat man sowas doch schon ausprobiert...
-
Sagt mal, hat hier wirklich keiner einen leisesten Schimmer von dem Problem?
Und bitte nicht nur "rumquacken" wie firefly, sondern einen Beitrag schreiben wenn man weiß wie und das es funktioniert.
-
Nod88 schrieb:
Ok, ich will meine Frage nochmal konkretisieren, eventuell wird es für euch damit etwas klarer.
Ich definiere in meinen Frame einen ostream, dieser soll mit dem EventHandler zu der EventHandleFunction übertragen werden.
Wie kann ich das machen?
.. so einfach gar nicht. Du kannst höchstens den std::ostream auf dem Heap anlegen (mit new std::ostream(..)) und dann den Pointer mit dem Event versenden.
Aber vielleicht erklärst Du mal, was Du eigentlich erreichen möchtest.Ansonsten könnte dieser FAQ-Beitrag über das Umleiten einer Ausgabe hilfreich sein.
-
Hast du in der setup.h
wxHAS_TEXT_WINDOW_STREAM = 1
stehen? Oder eine 0?
Falls da eine 0 steht, musst du entweder die Lib neu kompilieren mit dem geänderten Wert, oder das ganze ein wenig ändern und den wxStreamToTextRedirector verwenden.Scrolle runter zu Streams:
http://docs.wxwidgets.org/trunk/classwx_text_ctrl.htmlwxStreamToTextRedirector:
http://docs.wxwidgets.org/trunk/classwx_stream_to_text_redirector.htmlAnsonsten ist deine Verwendung eigentlich schon richtig, aber probier doch mal std::ostream statt nur ostream ;). Oder ich hab das Problem nicht richtig verstanden, du schreibst etwas wirr.
Mehr Code wäre vielleicht mal angebracht.edit:
Etwas wie eine Funktion: "GetVariable(*parent)" wäre sehr nützlich. Leider ist mir weder für Cpp noch wxWidgets so eine Funktion bekannt
.
Achso, jetzt ist der Groschen gefallen. Du brauchst einen Zeiger auf das wxTextCtrl. Dazu musst du entweder der Klasse diesen Zeiger mitgeben oder du verwendest wxWindow::FindWindow
-
Hi Scorcher24, genau, mein Problem hast du goldrichtig erkannt
Sorry wenn ich etwas verwirrend geschrieben habe, ist mir ehrlich nicht aufgefallen.Ich Habe nun versucht per FindWindow einen Pointer zu meinem wxTextCtrl zu erzeugen. Leider scheint das Fehlzuschlagen da ich die folgende Fehlermeldung erhalte:
error: no matching function for call to 'std::basic_ostream<char>::basic_ostream(wxWindow*)'
hiermal der Quelltext (auf das Grundgerüst reduziert, der Rest ist leider "nicht öffentlich"), eventuell ist der Fehler für dich ja offensichtlich.
gui.h
#include <wx/wx.h> class wxWCK : public wxFrame { public: wxWCK(const wxString& title); void OnClickCon(wxCommandEvent& event); void OnClickSta(wxCommandEvent& event); private: wxButton *connect; wxButton *start; wxTextCtrl *text; }; const int ID_CON = 100; const int ID_STA = 101; const int ID_MF0 = 102; const int ID_TEX = 103; void Connect(); void Start();
gui.cpp
#include "gui.h" wxWCK::wxWCK(const wxString& title) : wxFrame(NULL, ID_MF0, title, wxDefaultPosition, wxSize(400,300)) { wxPanel *panel = new wxPanel(this, -1); wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *hbox1 = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *hbox2 = new wxBoxSizer(wxHORIZONTAL); //Outputwidget text = new wxTextCtrl(panel, ID_TEX, _T(""), wxPoint(-1, -1), wxSize(1000, 1000), wxTE_MULTILINE); //redirecting stream to the outputwidget //std::ostream stream(text); stream << "Hello" << std::endl; connect = new wxButton(panel, ID_CON, _T("Connect")); start = new wxButton(panel, ID_STA, _T("Start")); hbox1->Add(text); hbox2->Add(connect); hbox2->Add(start); vbox->Add(hbox1, 1, wxEXPAND); vbox->Add(hbox2, 0, wxALIGN_LEFT | wxRIGHT | wxBOTTOM, 10); panel->SetSizer(vbox); Connect(ID_CON, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(wxWCK::OnClickCon)); //Connect(ID_STA, wxEVT_COMMAND_BUTTON_CLICKED, // wxCommandEventHandler(wxWCK::OnClickSta)); } void wxWCK::OnClickCon(wxCommandEvent& WXUNUSED(event)) { void Connect(); } void wxWCK::OnClickSta(wxCommandEvent& WXUNUSED(event)) { void Start(); } void Connect() { //Try to get a pointer to 'text' std::ostream stream(wxWindow::FindWindowById(ID_TEX)); stream << "Connected" << std::endl; } /* void Start() { //Try to get a pointer to 'text' std::ostream stream(wxWindow::FindWindowById(ID_TEX)); stream << "Started" << std::endl; } */
-
Du musst das Ergebnis von FindWindow nach wxTextCtrl casten.
-
Ich habe meine Funktion nun wie folgt geändert:
void Connect() { //Try to get a pointer to 'text' std::ostream stream((wxTextCtrl*) wxWindow::FindWindowById(ID_TEX)); stream << "Connected" << std::endl; }
Der Compiler meldet 0 Fehler, 0 Warnungen, aber wenn ich das Projekt laufen lasse reagiert das Programm nicht auf den Klick (also, der Inhalt von textändert sich nicht).
edit:
Ok, die noch nötigen Änderungen:
In der OnClickXXX-Fct müssen dievoid
raus, sonst wird die Zeile als Funktionsprototyp missverstanden.
und im wxWCK-Ctor müssen nochmal die Funktionsprototypen angelegt werden.
Dann läuft alles.