Zugiff von einer Klasse auf die andere



  • Ich bin neu hier im Forum und stelle eine Frage die u.U. schon zig mal gestellt wurde, finde jedoch keine Antwort.
    Bin erfahrener Delphi Worker und hab mal mit C++ unter Linux angefangen.
    Die Fakten

    Betriebsystem Linux
    IDE Kdevelop
    Bibliothek QT 3
    Sprache C++

    Erzeuge mir zwei Fenster mit unterschiedlichem Aussehen und Funktionalität.

    Fenster 1 Eingabe;
    Fenster 2 Ausgabe;

    Hier die Klassen nur als Rumpf:
    -----------------------------------

    class Eingabe : public QWidget
    {
        Q_OBJECT
    
    public:
    
        QPushButton* pushButton1;
    
    public slots:
    
    protected:
    
    protected slots:
    
    };
    

    --------------------------------

    class Ausgabe : public QWidget
    {
        Q_OBJECT
    
    public:
    
        QPushButton* pushButton2;
    
    protected:
    
    protected slots:
    
    };
    

    ---------------------------------------

    Von Eingabe habe ich die Klasse kdev1 abgeleitet
    Von Ausgabe habe ich die Klasse kdev2 abgeleitet
    in denen stecken meine eigenen Funktionen usw.
    Grundsätzlich haben kdev1 und kdev2 nichts mit einander zu tun.
    ----------------------------------------
    Hier die Klassen nur als Rumpf:

    class kdev1 : public Eingabe
    {
      Q_OBJECT
    
    public:
    
         void meinefunktion1(int& x = 0, int& Y = 0 );
    
    public slots:
         virtual void newausgabeSlot();
    protected:
    
    protected slots:
    
    };
    

    --------------------------------------

    class kdev2 : public Ausgabe 		
    {
     Q_OBJECT
    
    public:
    
    public slots:
    
    protected:
    
    protected slots:
    
    void closeEvent(QCloseEvent *event);
    };
    

    ---------------------------------------

    Meine Frage

    Ich möchte aus der Funktion der Klasse kdev2 ( z.B. closeEvent(..) )
    etwas in der Klasse kdev1 ändern z.B den Text von pushButton1 mit
    -> setText z.B.
    ---------------------------------------------------
    // Datei kdev1

    #include "kdev1.h"
    #include "kdev2.h"
    #include <qpushbutton.h>
    
    void kdev1::meinefunktion1 (int& x , int& y )
    {
    
    	// Ausgabe der Auswertung
    
    }
    
    void kdev1::newausgabeSlot() //Erzeugt zweites Fenster
    {
    
        kdev2 *ausgabeWin = new kdev2();
        ausgabeWin->show();
    }
    

    ---------------------------------------------------
    // Datei kdev2.cpp

    #include "kdev1.h"
    #include "kdev2.h"
    #include <qpushbutton.h>
    
    void kdev2::closeEvent(QCloseEvent *event)
    {
    kdev1::pushButton1->setText("Text"); :rage: //geht so nicht :rolling_eyes: 
    // 
    kdev1* vartest;
    vartest.pushButton1->setText("Text"); :open_mouth: //geht aber in anderer Instanz
                                                  und ändert nicht Text von   pushButton1
    
    }
    

    ------------------------------------

    So wie ich es hier mache geht es nicht Compiler/Linker motzen.

    Wie macht man das?
    Bitte nicht Antworten "Macht man nicht" sondern wie macht man es den Richtig
    in C++ ?



  • Erstens hat die Klasse kdev1 gar keinen Member "pushButton5", sondern nur das geerbte "pushButton1".

    Zweitens: Du brauchst auch eine Variable der Klasse, um deren Buttons ansprechen zu können (die Syntax mit :: klappt nur mit statischen Membern). Und dabei solltest du dann auch den Dialog erwischen, der tatsächlich angezeigt wird.

    Drittens: Was bedeteutet eigentlich "protected slots:"? (egal - du landets mal im richtigen Board)

    PS: sfds



  • Dieser Thread wurde von Moderator/in CStoll aus dem Forum C++ in das Forum Andere GUIs - Qt, GTK+, wxWidgets verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



    1. Benutze am Besten code-tags, dann kann man deinen Code besser lesen (und dann beschaeftigen sich auch mehr Leute mit deinem Problem)

    2. "Geht nicht" und "Compiler motzt" ist keine gute Fehlerbeschreibung

    3. Vielleicht dampfst du deinen Code etwas ein, damit man besser sehen kann wo das Problem denn nun liegt.

    Wie man fragen richtig stellt



  • Sorry, bin neu in Forum und muss mich zunächst an Eure Regeln gewöhnen. Trotzdem Danke.
    Hier die Fehlermeldung:
    /home/papel/kdev1/src/kdev2.cpp: In member function ‘virtual void kdev2::closeEvent(QCloseEvent*)’:
    ./edit.h:42: error: object missing in reference to ‘Form1::pushButton5’
    /home/papel/kdev1/src/kdev2.cpp:37: error: from this location

    protectet slots sind ähnlich wie Private Funktionen in QT

    pushButton5 entspricht pushButton1 in meinem Beispiel


  • Mod

    Du benötigst eine gültige Referenz bzw. einen gültigen Pointer auf das Fenster.
    Dies ist dann entweder eine Membervariable von deinem 2. Fenster, oder du Arbeitest mit einem Singleton als Controller,
    der dann wiederum die Referenz auf dein Fenster zurückgibt.



  • Das mit der Referenz ist mir klar nur 😃 wie mache ich das in C++ /QT. 🙂
    Hier noch ein der Teil von Main der das erste Fenster erzeugt.
    Auf was und wie muss ich aus der Funktion Zugreifen um den z.B. den Text von pushButton1 (5) zu ändern. Das Programm ist bereits sehr groß und deshalb habe ich nur ein Beispiel als Code dargestellt. Dadurch auch mal die Angabe pushButton1 und dann pushbutton5. Alles andere geht und die Referenzen stimmen.
    Aber wie komme ich von kdev2::beispielfunktion(); an pushbuttenx von kdev1 ; mainWin. Vielen Dank

    int main(int argc, char **argv)
    { 
    kdev1 *mainWin = 0;
    mainWin = new kdev1();
            app.setMainWidget( mainWin );
            mainWin->show();
    }
    

  • Mod

    Ich setzte jetzt mal voraus das du die Basics von C++ kannst:

    struct A
    {
    std::string foo;
    std::string Getfoo()const{return foo;}
    void Setfoo(std::string& f){foo = f;}
    }
    
    struct B
    {
       A* a;
       B():a(new A()){}
       void tuwas(){a->Setfoo("bar");std::cout << a->Getfoo();}
    }
    

    Du musst also entsprechend dafür sorgen, das deine Klasse einen gültigen Verweis auf die andere Klasse hat.
    D.h. wenn du die Klasse erzeugst, musst du dafür sorgen, das auch andere Klassen die dies wissen sollen, davon Kenntniss nehmen.



  • Danke!

    Programmiere seit 30 Jahren in den verschiedensten Sprachen. C++ mit QT ist jedoch recht neu für mich. In Assembler würde ich dem Linker einfach sagen das pushButtonx "extern" ist. Aber sowas in C wohl kein guter Stil. Werde das mal versuchen in mein Programm einzubauen. Hab da sicher noch ein Grundsätzliches Verständnissproblem.
    Da mein Programm sehr groß ist habe ich ein Beispiel geschrieben das dass Problem beschreibt aber nicht meinem Programm entspricht. Trenne die Klassen sonst schön von einander oder leite sie von einer gemeinsamen Basis ab. Hier will ich jedoch einfach den Text von einem Button in Fenster 1 von einer Funktion der Klasse abgeleitet von Fenster 2 ändern. Möchte eben nicht alles umstellen.

    Vielen Dank für die schnelle Hilfe 🙂 scheint ein gutes Forum zu sein.

    Wenn jemand mein konkr. Beispiel erweitern könnte wäre mir sicher noch schneller geholfen. Vielleicht hänge ich ja in einer Schleife ( in meinem Kopf ).



  • Auf die in main() erzeugte Variable/Instanz - mainWin - von Klasse kdev1
    kann ich aus einer Funktion die zur klasse kdev2 gehört nicht zugreifen.
    Eigentlich klar da diese ja nur local in main existiert.

    kdev1 *mainWin
    

    wo und wie kann ich - mainWin - den in der Klasse kdev2 bekannt machen.
    in der Klssendeklaration von kdev2 ? wie ?

    Vielen Dank


  • Mod

    enki04 schrieb:

    Auf die in main() erzeugte Variable/Instanz - mainWin - von Klasse kdev1
    kann ich aus einer Funktion die zur klasse kdev2 gehört nicht zugreifen.
    Eigentlich klar da diese ja nur local in main existiert.

    kdev1 *mainWin
    

    wo und wie kann ich - mainWin - den in der Klasse kdev2 bekannt machen.
    in der Klssendeklaration von kdev2 ? wie ?

    Vielen Dank

    Bitte keine Doppelpostings 😉

    Also um es noch mal zusammen zufassen, du hast 2 Fenster:
    kdev1 und kdev2. Ich nenn das jetzt mal A und B der Einfachheit halber 😉
    A soll wenn sich etwas ändert, auch in B etwas ändern, z.b. den Text des PushButtons.
    Du zeigst wo A erzeugt wird, jedoch kann man dort noch nix machen, da ja B nicht existiert.
    Also müsste A über einen Pointer vom Typ B verfügen, der am Anfang mit NULL initialisiert wird.
    Dann müsstest du, wenn B erzeugt wird, bzw. dort wo B erzeugt wird, A den Pointer auf die Instanz von B übergeben.
    Im Falle eines Änderungsevents in A müsstest du prüfen ob der Pointer auf B gültig ist, und dann entsprechend
    diese durchführen. Soweit die Theorie 😉

    ➡ Und Assembler ist eine ganz andere Welt als OOP Strukturierte Programmierung, wie es in der GUI Programmierung üblich ist.

    phlox



  • Oder schonmal an static gedacht? 😉



  • was spricht hier gegen signal/slot ?


  • Mod

    hellihjb schrieb:

    was spricht hier gegen signal/slot ?

    Nichts, wäre evtl. sogar die beste Lösung unter QT. Aber es geht halt auch anders in normalen C++.
    Kannst ja mal eine Signal/Slot Version posten...



  • Kannst ja mal eine Signal/Slot Version posten...

    du loest zb im closeEvent von kdev2 ein signal aus, das du (sobald beide objekte existent sind, zb nach der konstruktion von kdev2) per connect mit einem slot von kdev1 verbindest der in geeigneter weise auf das ableben von kdev2 reagiert.
    voraussetzung ist, dass es irgendeine zentrale schnittstelle gibt, der beide objekte bekannt sind und entsprechend die verbindung vornehmen kann.


Anmelden zum Antworten