not declared in this scope



  • @gokusa sagte in not declared in this scope:

    Um C++ besser zu lernen verwende ich dazu den Editor Geany, keine IDE.

    Ich glaube nicht, dass das zielführend ist. Eine IDE hätte dich auf das Problem hinweisen können. Die IDE ist ein Werkzeug, welches sich lohnt direkt mit zu lernen, zumindest meiner Meinung nach.

    @SeppJ sagte in not declared in this scope:

    aber vielleicht hat wxWidgets da irgendwelche Sonderregeln und das ist ok so (Ich spreche nicht wxWidgets, daher weiß ich die Antwort nicht)

    Ja, genau das. wxWidgets Klassen, die einen wxWidgets Parent mitbekommen werden von wxWidgets verwaltet, d.h. da darf man Speicher nicht ohne weiteres selbst wieder frei geben.



  • @Schlangenmensch @Th69 @SeppJ
    danke für die Antworten. Zum besseren Verständnis: Was das Lernen betrifft, an Büchern habe ich BREYMANN: C++ programmieren und Torsten T. Will C++ Das umfassende Handbuch. Begonnen habe ich mit kleinen Consolenprogrammen, danach erste GUI-Versuche mit Code::Blocks und wxWidgets. Dort bin ich soweit gekommen, dass der Nachbau meines JavaFX Programms startet, durch erste Methoden mit Buttons eine PostgreSQL- Datenbank-Verbindung aufgebaut und das Result in die Felder geladen wird. Dann kam ich nicht weiter, weil ein Zweites Result in die Rows eines Tabellen-Grids eingefügt werden soll. Dieses Grid muss dazu wohl angepasst werden, was aber schwierig ist, wenn man schon den von Code::Blocks erstellten Code nicht vollends versteht. So kam es, eben um die Grundlagen besser zu verstehen, zu dem Experiment in Geany. Der gepostete Test diente nur der Darstellung des Fehlers. Zurück dazu, es liegt wohl an wxWidgets:
    Nachdem ich in Zeile 35

    wxTextCtrl* TextCtrl1;
    

    eingefügt habe, klappt das Compilieren. Das Ausführen von TextCtrl1->SetValue klappt aber noch nicht: Segmentation fault.
    Danke für die Hilfsbereitschaft


  • Mod

    Zeigt dein Zeiger denn irgendwo hin? Irgendein Objekt musst du ihm vorher schon noch zuweisen.

    Wie ich sagte: Das sind dermaßen grundlegende Dinge, du hantierst hier mit Sprengstoff, ohne es jemals gelernt oder geübt zu haben.



  • @SeppJ
    tut mir leid, ich hätte die vollständige Zeile angeben sollen:

    TextCtrl1->SetValue(" mein neuer Text ");
    


  • Du mußt dann auch die Zeile mit der Variablen-Initialisierung anpassen:

    TextCtrl1 = new wxTextCtrl(...);
    

    Also den Typ wxTextCtrl* löschen, damit keine neue (lokale) Variable gleichen Namens angelegt wird!
    Das sind aber Grundlagen, welche auch in Java so gelten...



  • @gokusa ich bin kein Freund von generiertem Code. Insbesondere, wenn man nicht mit Default Sachen auskommt. Ich meine auch Code::Blocks empfiehlt noch wxWidgets 2.8. Als ich vor 5 Jahren ungefähr das erste mal mit wxWidgets in Berührung kam, war schon 3.1 draußen. Aktuell ist 3.2.

    Aber, Grundlagen wie Variablen Scope und so sollten schon da sein, da unterscheiden sich C++ und Java auch nicht so stark von einander.



  • @Th69
    Die Schreibweise für Member-Variablen war schon richtig:

    wxTextCtrl* TextCtrl1;
    

    Sie allein reicht im Konstruktor aber nicht, man muss auch die wxID angeben:

    const long ID_TEXTCTRL1 = wxNewId();
    

    Mehr zu wxWidgets habe ich hier gefunden:
    https://www.wxwidgets.org/docs/book/
    und die über 600 Seiten starke Anleitung (englisch) als PDF heruntergeladen:
    Cross-Platform GUI Programming with wxWidgets.pdf
    Die dort beschriebene Lösung des Event-Handlings mit Connect brachte nach einigen Fehlversuchen wegen Syntaxfehlern
    dann die Lösung, ich habe den eingangs geposteten Code auf das Wesentliche gekürzt:

    #include <wx/wx.h>
    
    class DBtoolApp : public wxApp { 
        public:
            bool OnInit();
    };
    
    class DBtoolFrame : public wxFrame {
        public:
            DBtoolFrame();
            void OnButton1Click(wxCommandEvent& event);
            const long ID_BUTTON1 = wxNewId();
            const long ID_TEXTCTRL1 = wxNewId();
        private:
            wxPanel* mainPanel;
            wxBoxSizer* mainBoxSizer;
            wxTextCtrl* TextCtrl1;
            wxButton* Button1;
    };
    
    IMPLEMENT_APP(DBtoolApp)
     
    bool DBtoolApp::OnInit() {
        DBtoolFrame *dbtoolFrame = new DBtoolFrame;
        dbtoolFrame->Show();
        SetTopWindow(dbtoolFrame);
        return true;
    }
    
    DBtoolFrame::DBtoolFrame() : wxFrame(nullptr, wxID_ANY, "Test-Tool") {
        mainPanel = new wxPanel(this, wxID_ANY);
        mainBoxSizer = new wxBoxSizer(wxHORIZONTAL);
        
        Button1 = new wxButton(mainPanel, ID_BUTTON1, "Write Text");
        Button1->SetForegroundColour(wxColour(40,30,200));
        mainBoxSizer->Add(Button1, 1, wxALL, 20);
        
        TextCtrl1 = new wxTextCtrl(mainPanel, ID_TEXTCTRL1, "...", wxDefaultPosition, wxDefaultSize);
        mainBoxSizer->Add(TextCtrl1, 1, wxALL, 20);
        
        mainPanel->SetSizer(mainBoxSizer);
        mainBoxSizer->SetSizeHints(this);
        SetSize(500, 400);
        TextCtrl1->SetFocus();
        Button1->SetDefault();
        Layout();
        Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&DBtoolFrame::OnButton1Click);
    }
    
     void DBtoolFrame::OnButton1Click(wxCommandEvent& event)
        { 
           wxString txt;
           txt = "mein neuer Text";
           TextCtrl1->SetValue(txt);
        }
    

    Danke für die Hilfe



  • @gokusa Achtung, Connect ist zwar nicht ausdrücklich depricated, aber trotzdem veraltet. Aktueller ist Bind Das ganze PDF würde ich mit vorsicht genießen, dass ist von 2006.

    Du brauchst auch nicht unbedint eine ID. Der default wxID_ANY reicht häufig aus.

    Versuch mach, anstelle der Connect Zeile

    Button1->Bind(wxEVT_BUTTON, &DBtoolFrame::OnButton1Click, this);
    

    wxNewId() ist deprecated. Wie geschrieben, nutze wxID_ANY wenn es egal ist, welche ID das Control hat. Und sonst, setze selbst eine ID, die aber größer ist als wxID_HIGHEST.



  • @Schlangenmensch
    hallo und danke für den Hinweis, ich werde mich am Wochende wieder damit befassen. In dem mit Code::Blocks und wxWidgets (3.0) erstellten Code wurde sowohl wxNewId() als auch Connect benutzt und ich glaubte, die Anleitung (PDF) wäre aktuell. Inzwischen habe ich die neuere Version im HTML Format gefunden und werde mich nur noch nach dieser richten. Ein Grund mehr, erstmal nur mit dem Editor die Grundlagen zu erlernen.



  • @Schlangenmensch
    deinen Empfehlungen folgend habe ich die Zeilen

    const long ID_BUTTON1 = wxNewId();
    const long ID_TEXTCTRL1 = wxNewId();
    

    und

    Connect(ID_BUTTON1,wxEVT_COMMAND_BUTTON_CLICKED,(wxObjectEventFunction)&DBtoolFrame::OnButton1Click);
    

    entfernt und beim Button Bind hinzugefügt.

    Button1->Bind(wxEVT_BUTTON, &DBtoolFrame::OnButton1Click, this);
    

    Es funktioniert, Danke. Mein eingangs geposteter Code mit ->Bind enthielt strukturelle Fehler, das konnte nicht klappen.


Anmelden zum Antworten