wxObject is an ambiguous base of MyFrame



  • Danke für die schnelle Antwort, aber so ganz klar ist mir das jetzt nicht.
    Wie würde den der Code richtig aussehen oder müsste ich den Code komplett umschreiben?


  • Mod

    Du solltest nicht von 2 Klassen gleichzeitig ableiten, wenn diese ein gemeinsames Parent haben.
    Das nennt man auch "diamond of death", da diese Ableitung eher unglücklich ist.

    Wenn du Ableitest dann immer in einem ist ein relation:
    Dein Dialog ist ein Dialog. Dein Frame ist ein Frame.
    Aber deine Framesklasse kann nicht Dialog _und_ Frame sein.
    Deine Frames Klasse hat eher einen Frame und einen Dialog.
    Du solltest hier also auf die Ableitung verzichten.

    Und schau dir evtl. mal GUI Editoren an, wie wxSmith in Code Blocks.

    phlox



  • Ok, das klingt logisch.
    Mein Grundproblem ist eigentlich: Wie kann ich von einem Fenster auf die Objekte von einem anderen Fenster, also eben eines Dialogfensters zugreifen und verändern?


  • Mod

    Du musst dem Fenster einen Zeiger oder eine Referenz auf das Objekt geben. Oder den Dialog lokal erstellen.

    class MyFrame;
    class MyDialog;
    
    class MainFrame : public wxFrame
    {
    MyFrame* myframe;
    
    MainFrame(/* parameter*/)
    {
      myframe = new MyFrame(this,wxNewId(),"Titel");
    }
    
    void OnShowDialog(wxCommandEvent& e)
    {
      MyDialog mydialog;
    if(mydialog.ShowModal() == wxID_OK)
      //dialog wurde mit ok beendet.
    }
    
    };
    

    phlox



  • Müssen dann aber nicht die Objekte von den einen Fenster auf den das andere zugreifen will nicht public sein? Und wie deklariere ich die Events wenn die in einer anderen Klasse liegen?


  • Mod

    Stony92 schrieb:

    Müssen dann aber nicht die Objekte von den einen Fenster auf den das andere zugreifen will nicht public sein?

    Nein, Elemente einer Klasse sind niemals public!
    Wenn du zugriff auf ein Objekt brauchst, musst du der Klasse jeweils ein eigenen Zeiger auf das Objekt geben, oder in einer Methode übergeben.

    MyDialog::Update(Data* data)
    {}//Dialog updaten.
    

    Aber generell solltest du dich vielleicht erstmal mit OOP und den Konzepten von C++ beschäftigen.

    Und wie deklariere ich die Events wenn die in einer anderen Klasse liegen?

    Du kannst events per connect an andere Klassen binden.

    phlox



  • Ich habe jetzt versucht das Programm so hinzubekommen, wie du es mir empfohlen hast. Sry aber ich stehe jetzt vor einem weiteren Problem:
    Mit Connnect() habe ich die Events jetzt an den Objekten gebunden und das Problem ist jetzt, dass der Zeiger von MainWindow ins Nichts zeigt, der Zeiger vom Dialogfenster aber funkt.

    //events.h
    
    class Events : public wxEvtHandler{
    
        public:
            Events() : wxEvtHandler(){
                fMain = new MainWindow(NULL);
                fMain->Show();            
    
                dLogin = new DialogLogin(NULL);
                dLogin->Show();
    
                InitEvents();
            }
    
        private:
            void InitEvents();
    
            MainWindow *fMain;
            DialogLogin *dLogin;
    
        protected:        
            void BtnConnectClick(wxCommandEvent& event);
            void BtnCancel02Click(wxCommandEvent& event);
            void BtnSendClick(wxCommandEvent& event);
    
    };
    
    //events.cpp
    void Events::InitEvents(){
    
        dLogin->BtnConnect->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Events::BtnConnectClick));
        dLogin->BtnCancel02->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Events::BtnCancel02Click));   
        fMain->BtnSend->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Events::BtnSendClick));
    
    }
    

    Nun versuche ich in z.B. BtnCancel02Click() auf fMain zuzugreifen, was aber zum Programmabsturz führ.

    void Events::BtnCancel02Click(wxCommandEvent& event){
        fMain->~MainWindow(); //Hier stürzt das Programm ab
        dLogin->~DialogLogin();
    }
    


  • Du musst der Connect-Methode auch den Event-Sink übergeben, in dem Fall einen Zeiger auf Deine eigene Klasse, also this . Das sieht dann so aus:

    void Events::InitEvents(){
    
        dLogin->BtnConnect->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Events::BtnConnectClick), (wxObject*)0, this);
        dLogin->BtnCancel02->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Events::BtnCancel02Click), (wxObject*)0, this);  
        fMain->BtnSend->Connect(wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Events::BtnSendClick), (wxObject*)0, this);
    
    }
    

    Siehe hier: http://docs.wxwidgets.org/trunk/classwx_evt_handler.html#a290d9b67348e74c1da8497955a4e35c

    @phlox: Ist es eigentlich schlechter Stil, Destruktoren direkt aufzurufen? Alternativen?



  • Danke!!
    Jetzt klappt alles 🙂 .



  • Hallo

    mikey schrieb:

    @phlox: Ist es eigentlich schlechter Stil, Destruktoren direkt aufzurufen? Alternativen?

    Ja den Destruktor direkt aufrufen ist afaik nicht gültig. Stattdessen lieber den Operator delete benutzen, bzw. für die GUI-Elemente von wxWidgets besser die Destroy-Methode.

    bis bald
    akari



  • thx akari, dann weiß ich Bescheid.


Anmelden zum Antworten