Forum: PC-Programmierung Objekt von Klasse A in Klasse B lesen (C++)


von Samuel (Gast)


Angehängte Dateien:

Lesenswert?

Hallo alle zusammen:

Programmiersprache: C++
IDE: Visual Studio + QT Plugin

Folgende Anwendung habe ich (seh bitte Anhang)

Klasse A:
1
//Header File
2
class MainWindow : public QMainWindow
3
{
4
  Q_OBJECT
5
6
public:
7
  MainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
8
  ~MainWindow();
9
  public:
10
    QString getKundenName() const;
11
};
12
//Source File
13
MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
14
  : QMainWindow(parent, flags)
15
{
16
  ui.setupUi(this);
17
}
18
19
QString MainWindow::getKundenName() const
20
{
21
  return ui.kundenNameLineEdit->text();
22
}

Klasse B:
1
#include "MainWindow.h"
2
class DatabaseManager
3
{
4
private:
5
DatabaseManager();
6
~DatabaseManager();
7
MainWindow mainWindow;
8
public:
9
QString getKundenNr();
10
11
};
12
13
// Source File
14
QString DatabaseManager::getKundenNr()
15
{
16
  QString returnValue = NULL;
17
  QSqlQuery query;
18
  //returnValue = .......// hier möchte ich das Objeckt von Klasse A holen.
19
                             // Dieses Objeckt beinhaltet das Value von "LineEdit" der Klasse A  
20
                 
21
  returnValue = mainWindow.getKundenName(); // Der Value  ist leer ? 
22
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Samuel schrieb:
> class DatabaseManager
> {
> private:
>   DatabaseManager();
>   ~DatabaseManager();
>   MainWindow mainWindow;

> ..
>   returnValue = mainWindow.getKundenName(); // Der Value  ist leer ?

Ist denn "mainWindow" ernsthaft nur und ausschließlich privates Member 
von "DatabaseManager"?

Wenn nicht, dann ist das eine zweite Objektinstanz, die natürlich 
nichts von der anderen, anderswo angelegten und verwendeten ersten 
Objektinstanz weiß.

von Karl H. (kbuchegg)


Lesenswert?

Rufus Τ. Firefly schrieb:

> Wenn nicht, dann ist das eine zweite Objektinstanz, die natürlich
> nichts von der anderen, anderswo angelegten und verwendeten ersten
> Objektinstanz weiß.

Abgesehen davon solltest du dir auch überlegen, warum und wieso ein 
DatabaseManager irgendetwas vom einem Mainwindow wissen soll. Der Name 
'DatabaseManager' legt nahe, dass sich diese Klasse um eine Datenbank 
kümmert. Mit einem Fenster hat so eine Klasse überhaupt nichts am Hut. 
Wie und wo die Werte der Datenbank angezeigt werden, das ist nicht ihr 
Bier.

Ein wichtiger Punkt in der objektorientierten Programmierung ist das 
strikte Einhalten von Zuständigkeiten. Jede Klasse ist für irgendetwas 
zuständig. Und nur darum kümmert sie sich und sonst um nichts anderes.

In deinem Beispiel mag es vielleicht eine Klasse 'Kunde' geben. Diese 
Klasse vereinigt in sich all die Daten, die einen Kunden ausmachen. Der 
DatabaseManager liefert auf Anforderung so einen Kunden (wie auch immer 
der identifiziert wurde) und die Window-Klasse kann so einen Kunden 
anzeigen bzw. die Elemente, die einen Kunden ausmachen, zum verändern 
anbieten.

Der verbindende Kit aussen rum sorgt dann dafür, dass so ein 
Kunden-Objekt in das Eingabafenster übergeben wird bzw. das veränderte 
Objekt wieder zum DataBaseManager zurück kommt, welcher dann die 
Datenbank damit auf den neuesten Stand bringt.

: Bearbeitet durch User
von ggg (Gast)


Lesenswert?

Arbeitet man bei QT nicht mit MVC und Signal& Slots? Ich würde mir das 
nochmal überlegen an deiner Stelle.

von Sven B. (scummos)


Lesenswert?

Doch tut man. Aber ziemlich genau diesen Thread gab es vor einer Woche 
schonmal ... und da wurde eigentlich schon alles gesagt.

Beitrag "QT + Visual studio"

von Samuel (Gast)


Lesenswert?

Hallo Sven B,



aber hier ich benutze zwei Klassen A, und B.
Wie soll ich den Value von einem Objekt der Klasse A in eine Klasse B 
holen?
Das kappiere ich nicht ganz?
Sorry

Wenn es die Rede über einem Objekt der in den gleichen Klasse ist, dann 
kann ich Signal und Slot benutzen.

von Sven B. (scummos)


Lesenswert?

Signals können von jedem beliebigen QObject zu jedem beliebigen anderen 
Objekt versendet werden.

Die Fragestellung "Wie soll ich den Value von einem Objekt der Klasse A 
in eine Klasse B holen?" lässt sich in dieser Allgemeinheit nicht 
beantworten -- in der Beantwortung dieser Frage liegt ein nicht 
unwesentlicher Teil des Entwurfs deiner Anwendung versteckt.

Ich kenne halt dein Ziel nicht so genau aber in diesem Fall würde ich 
vorschlagen (das habe ich übrigens schonmal vorgeschlagen) dass nicht 
die Datenbank-Klasse von MainWindow weiß, sondern das MainWindow von der 
Datenbank-Klasse, und auch das MainWindow schaut wann sich die Daten 
ändern und das der Datenbank-Klasse dann mitteilt.

Wenn die Datenbank-Klasse irgendwas mit irgendwelchen Widgets zu tun 
hat, ist der Aufbau deiner Anwendung höchstwahrscheinlich mindestens 
ungeschickt.

Grüße,
Sven

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Samuel schrieb:

> aber hier ich benutze zwei Klassen A, und B.

Trugschluss,
Du benutzt nicht 2 Objekte. Du hast mehr!
Da ist auch noch das übergeordnete Objekt (oder die main Funktion), 
welches alles zusammenhält.

Dein MainWindow entsteht ja nicht aus dem luftleeren Raum heraus, 
sondern es wird von main() erstellt. Dort erstellst du auch das andere 
Objekt und gibst ihm den Pointer zum Mainwindow.

D.h. du musst eine Ebene höher gehen.
Nicht das A Objekt weiss irgendwie magisch vom B Objekt. Sondern der 
Programmteil, der A Objekt UND B Objekt erzeugt, stellt die beiden 
einander vor.

von Samuel (Gast)


Angehängte Dateien:

Lesenswert?

Das ganze fachliche Konzept sieht so aus:

Der user trägt in Textfield1 irgendwas.... z.B. seine Name dann wird er 
Enter drücken.

nach dem Drücken wird der Name bzw.(Value von der textfield1) in der 
Database gelesen und der dazugehörige Vorname in der textfield2 
reinkopiert.

seh bitte Anhang:

VornameDataBaseHolen() sieht so aus:
1
void MainWindow::vornameDateBaseHolen()
2
{
3
  if (ui.lineEditName->text().isEmpty())
4
  {
5
    ui.lineEditVorname->setText(DatabaseManager::getInstance().getVorName());
6
  }
7
else{
8
.....
9
}
10
}
1
QString DatabaseManager::getVorName()
2
{
3
QString returnValue = NuLL;
4
returnValue = .....?
5
6
}

von Karl H. (kbuchegg)


Lesenswert?

Samuel schrieb:
> Das ganze fachliche Konzept sieht so aus:

Das ist kein Konzept.
Das ist maximal eine Vorstudie, wie eine Benutzeroberfläche aussehen 
könnte.

> Der user trägt in Textfield1 irgendwas.... z.B. seine Name dann wird er
> Enter drücken.
>
> nach dem Drücken wird der Name bzw.(Value von der textfield1) in der
> Database gelesen und der dazugehörige Vorname in der textfield2
> reinkopiert.

Eben. Dazu muss aber die Database nichts vom Mainwindow wissen.

In deinem Fall muss das Minwindow von der Database wissen, wenn man 
dieses Drücken von Enter nicht überhaupt aus dem Mainwindow insofern 
raushält, dass es seine Applikation darüber benachrichtigt, dass eine 
Engabe abgeschlossen wurde und die Applikation alles weitere in die Wege 
leitet.

Zuständigkeiten! Warum glauben einem das die Neulinge nie?

1
               +----------------+
2
               |   Applikation  |
3
               +----------------+
4
                  ^ |       ^ |
5
                  | |       | |
6
         +--------+ |       | +------+
7
         | +--------+       +------+ |
8
         | |                       | |
9
         | v                       | v
10
      +-------------+         +-----------+
11
      | Mainwindow  |         | Datenbank |
12
      +-------------+         +-----------+

lies die Pfeile als 'kommuniziert mit' (im Sinne von Funktionsaufrufen).
Die Applikation erzeugt das Mainwindow und auch das Datenbank-Objekt. 
Wenn das Mainwindow etwas hat, was abgeschlossen ist, benachrichtigt es 
seine Applikation, die sich die Daten holt und zb. in eine Datenbank 
schreibt. Sie könnte die Daten auch per EMAil veschicken, aber bei dir 
schreibt sie die eben in die Datenbank. Was mit den Daten geschehen 
soll, interessiert aber weder das MainWindow noch das Datanbank Objekt. 
Das MainWindow interessiert sich deswegen nicht dafür, weil seine 
Zuständigkeit damit beendet ist, wenn die Eingabe gemacht wurde. Was 
weiter mit den Daten zu geschehen hat, ist nicht sein Bier.
Das Datenbank Objekt wiederrum interessiert sich nicht dafür, wo die 
Daten herkommen, die es in die Datenbank zu schreiben hat oder aus ihr 
zu lesen hat. Wenn es von der Applikation den Auftrag kriegt etwas zu 
schreiben, dann macht es das. Aber ob die Daten per EMail oder 
Brieftaube eingetroffen sind, das interessiert es nicht die Bohne.
Der verbindende Kit, das ist die Applikation. Dort werden die Objekte 
erzeugt und dort ist auch die Logik beheimatet, welche Daten von wo nach 
wohin gehen. Die könnten ja auch von der Datenbank zum Drucker gehen. 
Egal wer wohin geht, die Applikation ist die Schaltzentrale.

In manchen Fällen kann man in Qt der MainWindow Klasse auch die Aufgaben 
der Applikation übertragen. Aber allzuoft stellt sich dann zu einem 
späteren Zeitpunkt heraus, dass die Idee nicht so gut war, wie man 
zuerst dachte.

: Bearbeitet durch User
von Sven B. (scummos)


Lesenswert?

Kommt halt drauf an wie kompliziert die Anwendung ist. Bei einfachen 
Anwendungen kann diese "Controller"-Logik locker in's Mainwindow, bei 
etwas komplexeren Sachen lohnt es sich dann das besser zu strukturieren.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.