Forum: PC-Programmierung GUI: Variable Anzahl von Parametern


von Thomas (Gast)


Lesenswert?

Hallo,

ich suche kreative Denkanstösse zu folgendem Problem. Die Hoffnung ist,
dass jemand die für das Problem übliche (und daher elegante) Lösung
kennt oder das sich in der Diskussion Ideen entwickeln, die mir
zumindest mehr gefallen, als der derzeitige Weg.

Es geht um die Eingabe von Parametern unterschiedlicher Anzahl an einer
GUI. Am klassischen Beispiel der OOP erklärt: Man hat eine Klasse Tiere
und davon abgeleitet beispielsweise Hunde und -ähm- Ameisen. In einem
Dialog sollen nun Eigenschaften des jeweiligen Tieres eingegeben werden
können, wobei diese Tiere unterschiedliche Eigenschaften in
verschiedener Zahl haben können. Der Dialog selbst ist unproblematisch,
da können Parameter und zugehöriger Wert einfach in einer Tabelle
stehen, aber wie am geschicktesten an die Information von den Objekten
an die GUI und zurück? Sprich, wie geben die Objekte die "Namen" der
Parameter an den Dialog und wie kommen dann die Werte zurück. (Die sind
der Einfachheit halber alle von gleichen Typ..)

Mein derzeitiger Lösungsansatz beinhaltet eine Klasse "param" mit
zwei Vektoren "Name" und "Wert" und jede Klasse (jedes Tier)
enthält ein Objekt  "param". Das erfordert aber bei jedem Tier zwei
Methoden, die "param" vor dem Dialog initialisieren bzw. nach dem
Dialog die Variablen des Tiers aus "param" holen. Irgendwie erscheint
mir das ganze wenig elegant.

Teile des Konzepts erinnern schon an Serialisierung (NVP und das Ein-
und Auslesen der Parameter), aber was macht man dann in dem Dialog mit
den serialiserten Daten...


Viele Grüße

von Karl H. (kbuchegg)


Lesenswert?

Im Prinjzip bist Du auf dem richtigen Weg.
Do solltest es aber anders implementieren.

Zunaechst mal hat so ein Tier 'Eigenschaften'. Was
sind 'Eigenschaften'? Eigenschaften sind eine Ansammlung
von 'Eigenschaften' (Hier gehts um: Mehrzahl - Einzahl,
eine Eigenschaft versus viele Eigenschaften. Das letztere
baut auf dem ersteren auf).

Was wiederum ist eine Eigenschaft. Woraus besteht sie?
Nun eine Eigenschaft hat einen Namen und einen Wert. (Fuers
erste. Da wird wahrscheinlich noch was dazu kommen. Zb.
Wertebereich, Darstellungsform, etc.)

Also:

class Eigenschaft
{
  public:
    .....

  protected:
    std::string   m_Name;
    std::string   m_Wert;
};

Da ist sie. Eine einzelne EIgenschaft.
Daraus bauen wir gleich mal eine 'Menge von Eigenschaften'

class SetOfEigenschaften
{
  public:
    .....

  protected:
    std::vector< Eigenschaft > m_Set;
};

Tja. Und nachdem du das hast, verpasst Du jetzt jedem Tier
so eine Eigenschaftsmenge:

class Tier
{
  ....

  protected:
    SetOfEigenschaften m_Eigenschaften;
};

und das wars. Jedes Tier, dass davon ableitet, erbt automatisch
ein SetOfEigenschaften, in dem es jede beliebige Information
speichern kann.

Dein Dialog kuemmert sich dann nicht mehr um Tiere. Dein Dialog
kriegt ein SetOfEigenschaften zur Verfuegung gestellt. In dem
darf er Aenderungen machen (oder auch nicht. Wer sagt, dass eine
Eigenschaft nicht ein weiteres Attribut hat, dass zb. ReadOnly
steuert. Oder das zb. die Eigenschaft im Dialog vor dem Benutzer
versteckt [sowas wie 'interne' Variablen eines Objektes], ...)

Der wesentliche Unterschied: Du musst zunaechst mal eine
Klasse aus Namen-Wert bauen und erst dann wird daraus ein
vector aufgebaut. Nicht 2 vectoren in dem jeweils die Namen
und die Werte gespeichert sind. Sowas bringt Dich auf lange Sicht
um.

von Thomas (Gast)


Lesenswert?

Hallo Karl Heinz,

besten Dank für deine Anregungen.


> Nun eine Eigenschaft hat einen Namen und einen Wert. (Fuers
> erste. Da wird wahrscheinlich noch was dazu kommen. Zb.
> Wertebereich, Darstellungsform, etc.)

Genau, ich hab es auch tatsächlich schon mit Namen, Wert und
Wertebereich implementiert.


> class Eigenschaft
> class SetOfEigenschaften
> Tja. Und nachdem du das hast, verpasst Du jetzt jedem Tier
> so eine Eigenschaftsmenge:

Da besteht nur ein geringer Unterschied zu meiner Lösung, du bildest
erst Name-Wert-Paare, um die in einem Vektor aufzusammeln und bei mir
enthält "SetOfEigenschaften" halt mehrere Vektoren. Da aber
"SetOfEigenschaften" dies in sich kapselt, treten beide Versionen
nach außenhin gleich auf. Was halt statt Vektoren gleich noch möglich
wäre, ist eine Map mit dem Paar Name-Wert (bzw. statt des Wertes wieder
ein Verbund von Wert und Wertebereich etc.).


> Jedes Tier, dass davon ableitet, erbt automatisch
> ein SetOfEigenschaften, in dem es jede beliebige Information
> speichern kann.

Ja, nicht anders geht es meinen Dingen auch.


> Dein Dialog kuemmert sich dann nicht mehr um Tiere. Dein Dialog
> kriegt ein SetOfEigenschaften zur Verfuegung gestellt. In dem ...

Richtig, so handhabe ich es jetzt schon. Der Dialog bekommt nur das
Konstrukt mit den Parametern. Auf der Seite ist das ja auch alles schön
und gut. Die Klasse "SetOfEigenschaften" beinhaltet Accessoren die bei
Zugriff auf die Werte den Wertebereich testen. Unschön ist bei meiner
Konstruktion allerdings, dass die "Tiere" dynamisch in ihrem
Konstruktor das "SetOfEigenschaften" definieren, also Namen,
Defaultwerte und Wertebereich angeben. "SetOfEigenschaften" hat also
eine Zugriffsfunktion die dies erlaubt. Dann verhindert allerdings
nichts, dass der Dialog dies auch tut. Zur Zeit habe ich ein Flag
dafür, was nach Initialisierung gesetzt wird. Das ist halt eine Prüfung
zur Laufzeit die mir nicht gefällt, besser wäre eine Prüfung zur
Compile-Zeit, aber mir fällt nichts gescheites ein.


> Der wesentliche Unterschied: Du musst zunaechst mal eine
> Klasse aus Namen-Wert bauen und erst dann wird daraus ein
> vector aufgebaut. Nicht 2 vectoren in dem jeweils die Namen
> und die Werte gespeichert sind. Sowas bringt Dich auf lange Sicht
> um.

Der Unterschied ist mir klar und mir gefällt die Idee erst Paare zu
bilden auch besser :-), aber ein richtiges Problem kann ich nicht
erkennen, da das Ganze in einer einzigen Klasse gekapselt ist und das
Problem dort nicht hinaustreten kann...


Mein eigentliches Problem und die wahre Narretei an der Implentierung
ist aber das folgende: Historisch gewachsen sind die ganzen Klassen
ohne Dialoge (und deswegen suche ich ja jetzt das "Designpattern für
solche Fälle), haben also ihre Parameter in Form klassischer Variablen
(POD-typen) mit den üblichen Zugriffsmethoden. Dann kam die
Paramtersammlung für Dialoge hinzu und das Problem ist, dass jetzt
Informationen doppelt vorhanden sind. Dies wiederum erfordert, dass
vor und nach jedem Dialog die Daten übertragen werden. Das ist der
Schwachsinn, den ich nicht gleich behoben habe. Die traditionellen
Daten müssen weg, nur noch die Parametersammlung wird verwendet,
Accessoren müssen diese verwenden und alle Methoden selbst müssen auch
die Accessoren verwenden statt auf Interna direkt zugreifen zu können.

Viele Grüße

von Hans (Gast)


Lesenswert?

du kannst listeneinträgen (egal obs jetzt eine richtige liste oder ein
tree oder was auch immer ist) zumindest in der mfc ein DWORD mitgeben..
das nennt sich item data.. da schiebst du einfach einen pointer auf
deine daten-klasse mit und schon weist du wo die daten hinmüssen ;)

wie das unter vista gemacht werden wird ist mir nicht bekannt...

du musst dir also nur eine schöne basis-datenklasse machen, alle
anderen davon ableiten damit das gut geht...

73

von Thomas (Gast)


Lesenswert?

Hallo Hans,

danke auch für deinen Kommentar, aber MFC und andere proprietäre, nicht
portable Lösungen kommen mir nicht ins Haus. Evtl. kann man sich
natürlich die dahinter stehende Idee "ausborgen". Von einem Vista
hab' ich noch nichts gehört, was soll das sein?

Eine Klasse zur Aufsammlung der Daten (wie auch von Karl Heinz
beschrieben) paarweise in Liste/Vektor/Map ist ja keine Problem, die
Nutzung in dem Dialog auch nicht, nur die Verwendung einer solchen
Liste in den einzelnen Objekten erfordert dort einen deutlich höheren
Implentierungsaufwand und auch höher Laufzeitanforderungen...

Gruß, Thomas

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.