Datenaustausch zwischen mehreren Objekten?

Alles rund um die Programmierung mit Qt
Antworten
gransi
Beiträge: 5
Registriert: 8. November 2004 09:00

Datenaustausch zwischen mehreren Objekten?

Beitrag von gransi »

Ich habe vor kurzen mit C++ angefangen zu programmieren. Derzeit programmiere ich unter Linux mit Qt-Gui einen Programm, dass Daten von der seriellen Schnittstelle einlesen soll und je nach ausgewählten Modus anders anzeigt.

Der derzeite Aufbau sieht so aus, dass ich ein Hauptfenster mit einen Tab-Dialog habe. Auf jeder Tab-Seite befindet sich einen selbst programmiertes Objekt ( sogenanntes QWidget für Qt-Programmieren ). In der letzen Tab-Seite ist ein Textfeld das als Log funktioniert. Für das einlesen der Daten von der seriellen Schnittstelle ist eigenes Objekt( IO-Objekt ) zuständig.

Meine Frage ist, wie muss ich die Objekte verbinden das diese untereinander die Daten austauschen.
z.B. Wenn in der ersten Tab-Seite etwas passiert, dann soll das Objekt einen Eintrag in der letzen Tab-Seite einfügen. Oder wenn die zweite Tab-Seite geöffnet ist dann soll dieses Objekte die Daten vom IO-Objekt einlesen.
Aber wie realisiere ich den Datenaustausch, weil die Objekte wissen nichts voneinander. Meine Vorschlag wäre das ich die Adressen von den Objekten im Hauptfenster-Objekt speichere und das die einzelnen Objekte sich dort die Adresse holen.
Aber ich denke, es gibt doch irgendwie eine elegantere Lösung.

Stark vereinfachter Code des aktuellen Standes:

Code: Alles auswählen

class Hauptfenster(...) : public QWidget 
{ 
public: 
     Haupfenster(...) : QWidget(...) 
     { 
        // Tab-Dialog einfügen 
        QTabDialog *tabdialog = new QTabDialog(this); 
        //Objekte einfügen 
        tabdialog->addTab( ErsteTab( this )); 
        tabdialog->addTab( ZweiteTab( this )); 
        tabdialog->addTab( DritteTab( this )); 
     } 
} 

class ErsteTab(...) : public QWidget 
{ 
public: 
     ErsteTab(...) : QWidget(...) 
     { 
       //Labels und Buttons einfügen 

       // Mit einem Timer die Daten vom IODaten holen und in den Labels     
       // darstellen 

     } 
} 

class ZweiteTab(...) : public QWidget 
{ 
public: 
     ZweiteTab(...) : QWidget(...) 
     { 
       //Labels und Buttons einfügen 

       // Mit einem Timer die Daten vom IODaten holen und in den Labels     
       // darstellen 
     } 
} 

class DritteTab(...) : public QWidget 
{ 
public: 
     DritteTab(...) : QWidget(...) 
     { 
       //Textfeld einfügen 
     } 

     void addTextEintrag( char ctext ) 
     { 
        textfeld->addtext(ctext); 
     } 
} 

class IODaten() 
{ 
public: 
     IODaten() 
     { 
        //Schleife starten zum Daten einlesen von der seriellen Schnittstelle 
     } 

     int getDaten() 
     { 
        return eingelesenDaten; 
     } 
} 

Mein Vorschlag soll so auschauen:

Code: Alles auswählen

class Hauptfenster(...) : public QWidget 
{ 
public: 
     Haupfenster(...) : QWidget(...) 
     { 
        // Tab-Dialog einfügen 
        QTabDialog *tabdialog = new QTabDialog(this); 

        ersteTab = new ErsteTab( this ); 
        zweiteTab = new ZweiteTab( this ); 
        dritteTab = new DritteTab( this ); 

        tabdialog->addTab( ersteTab ); 
        tabdialog->addTab( zweiteTab ); 
        tabdialog->addTab( dritteTab ); 
     } 

     IODaten *daten; 
     ErsteTab *ersteTab; 
     ZweiteTab *zweiteTab; 
     Dritte *dritteTab; 
     IODaten *IOdaten; 
} 

class ErsteTab(QWidget *parent..) : public QWidget 
{ 
public: 
     ErsteTab(QWidget *parent,...) : QWidget(...) 
     { 
       //Labels und Buttons einfügen 
       dritteTab = parent->dritteTab; 
       dritteTab->addTextEintrag("Erste Tag funktioniert"); 
       daten = parent->IOdaten; 
     } 
private: 
     IODaten *daten; 
     DritteTab *dritteTab; 
} 

class ZweiteTab(QWidget *parent..) : public QWidget 
{ 
public: 
     ZweiteTab(QWidget *parent..) : QWidget(...) 
     { 
       //Labels und Buttons einfügen 

       // Mit einem Timer die Daten vom IODaten holen und in den Labels     
       // darstellen 
       daten = parent->daten; 

       label->text( daten->getDaten ); 
     } 
private: 
     IODaten *daten; 
} 

Ich hoffe ihr versteht was ich meine. Denn mein Vorschläg ist glaube ich zu Aufwendig und für die Wartung des Programmes sehr schlecht.

Danke im Voraus
gandalf
Beiträge: 39
Registriert: 31. August 2004 17:00
Wohnort: Varel
Kontaktdaten:

Beitrag von gandalf »

Hallo

Also ich würde sagen deine Lösung schreit geradezu nach Signals and Slots, diese sind wenn du dir nicht die mühe machen willst ein Visitor-Pattern zu implementieren das was du suchst.

Prinzip es gibt ein Sender (S) der ein Signal hat
und ein Reciever(R) der ein Slot hat
diese werden mit einem connect verbunden
Vorgehen/Beispiel:

Code: Alles auswählen

// in .h (S)
signals:
  void mysignal(datentyp,...);
// in .h (R)
public slots:
  void myslot(datentyp,...);

//in .cpp (S)
emit mysignal(daten,...);

//in .cpp (R)
void myWidget::myslot(datentyp daten,...)
{
//was soll passieren wenn
}

// dort wo beide Objekte sind
connect(S,SIGNAL(mysignal(datentyp,...)), R,SLOT(myslot(datentyp,...)));
außer beid der Slotimplemetierung stehen überall nur Datentypen ohne Variablennamen, Datentypen könne auch eigene Klassen oder Structs sein

du kannst ein Signal mit beliebig vielen Slots connecten
Du mußt allerdings darauf achten das die Anzahl der Datentypen und die Art der Datentypen gleich sein muß

signal(int,int) paßt nur zu slot(int,int) etc

ein Siganl das gesendet wird führt die Operation im Slot sofort aus auch im hintergrund

Ach ja Sender und Reciever müssen Pointer sein aber das sollten Widgets eh immer sein

Viel Spaß damit und guten Rutsch
gandalf
benutzte QT 3.2 nc auf w2k
gransi
Beiträge: 5
Registriert: 8. November 2004 09:00

Beitrag von gransi »

Gibt es eigentlich eine Möglichkeit den Empfänger wegzulassen, damit das Signal an alle Objekte gesendet wird und je nach Signal meldet sich ein Objekt dementsprechend zurück.
gandalf
Beiträge: 39
Registriert: 31. August 2004 17:00
Wohnort: Varel
Kontaktdaten:

Beitrag von gandalf »

So weit ich das übersehen kann nicht, jedes Object muß einen dementsprechenden Slot haben, wie gesagt das ganze funktioniert ähnlich dem Visitor Prinzip auch dort muß jedes Objekt angemeldet werden und soweit ich mich entsinnen kann auch Methoden für an- und abmelden besitzen.

gandalf

Edit
aber wenn ich mir die Doku so ansehe könnte das doch gehen, allerdings hab ich da keine Erfahrung mit
http://doc.trolltech.com/3.3/qobject.html#connect
und dort unter

Code: Alles auswählen

bool QObject::connect ( const QObject * sender, const char * signal, const char * member ) const 
benutzte QT 3.2 nc auf w2k
Antworten