QT und Templates


  • Mod

    Weil du vorher wegen CRTP fragtest:
    CTRP würde die hier erlauben die Basisklasse auszutauschen. QLineEdit/QTextEdit oder andere UI Klassen problemlos möglich.

    Was ich jetzt allerdings nicht verstehe, wie passt ein LineEdit zu einem Container?

    Was Model View angeht, das habe ich in meiner Einführung in Qt erwähnt.



  • Mechanics:
    Klar, in dem Post oben http://www.c-plusplus.net/forum/p2349380#2349380 nutze ich das Template-Argument.

    Es gibt zwei Klassen, die man dort übergeben kann, die aber eben dieselbe Schnittstelle definieren, in diesem Fall meinetwegen getText(). Und wie oben erwähnt gibt es aber im Falle von meinetwegen Employee eine Spezialisierung der Klasse, wofür dann paintEvent() überschrieben wird.

    Willst du eine GUI bauen, die "generisch" irgendwelche Adressen anzeigen kann? Und dann AddressView<Contact> oder AddressView<Employee> oder sonst was erstellen und da drin greifst du auf T.name() zu? Sowas ist wohl kaum realistisch.

    Doch, im Grunde schon. Die müssen halt die richtige Schnittstelle definieren. Genau so, wie man vielen algorithm-Funktionen auch ein Iterator-Paar als Template-Argument übergeben kann und definiert sein muss, dass es begin() und end() gibt. Wieso ist das hier plötzlich nicht mehr realistisch?

    phlox81:
    Okay, dann habe ich dein CRTP-Beispiel richtig verstanden. 🙂

    Wie Models in QT funktionieren, weiß ich. Das nützt mir aber für den Fall nichts (überhaupt finde ich die QT-Modellklassen unglaublich schlecht zu handhaben, aber was soll's).

    Für die Zerlegung des Containers in einen String werden die einzelnen Elemente in ihrer String-Repräsentation mit ',' konkateniert angezeigt. Wenn man etwas am String ändert, wird geparst und es wird wieder zurückverwandelt. Da das Parsen und Verwandeln in einen String durchaus für mehrere text-like QT-UI-Klassen passen soll, gibt es da natürlich eine Klasse, die das übernimmt. Aber die muss ja wohl dem QLineEdit bekannt sein. Da sich diese Texte aber wieder in diversen Eigenschaften unterscheiden (definiert durch Templateargument), muss die UI-Klasse zur Verwendung aller solcher Typen eben Template sein.



  • Eisflamme schrieb:

    Wieso ist das hier plötzlich nicht mehr realistisch?

    Weil es viel seltener vorkommt. Es ist unrealistisch, dass es viele Klassen gibt, die eine sehr ähnliche Schnittstelle haben und die man auf die gleiche Art und Weise darstellen kann. Du wirst in deinem Programm vielleicht mit Mühe und Not zwei Klassen finden, die da passen, und später kommt noch eine Methode hinzu, die du brauchst, und die andere Klasse hat die plötzlich nicht mehr.



  • Ich suche doch nicht danach. Ich habe mein Backend und da ist das mit der Schnittstelle genau so definiert. Da kannst Du auch jedes policy-based-design nehmen und hast die gleiche Schnittstelle. Also ich kann mir da viele Anwendungsmöglichkeiten vorstellen. Backend hat Templates -> will ich darstellen. Wenn das unrealistisch ist, dann ist es unrealistisch, dass man Templates in C++ nutzt. 😉 Oder was missverstehe ich hier?

    Nochmal: Ich suche die Möglichkeit im UI verschiedene Ausprägungen (definiert durch Templateargumente) eines Templates darzustellen, deren Templateklassen dieselbe Schnittstelle definieren, wobei das Anzuzeigende vom gleichen Typ (std::string) für alle Templateklassen ist und es deswegen für die UI-Klasse kein Problem ist, auch die gesamte Palette der Templateklassen zu akzeptieren.

    Und ja, manche Templateklassen haben spezielle Methoden. Daher gehört die UI-Klasse ja teilweise auch spezialisiert - das betrifft aber nur wenige Methoden.



  • Vielleicht kann man das Problem mit einem anderen Beispiel illustrieren. Sagen wir meinetwegen, dass ich als Daten wirklich einfach nur vector<int> und vectorstd::complex habe. Nehmen wir jetzt meinetwegen zur Darstellung eine QListView, dort soll für den int-vector in jeder Zeile eine Zahl und bei der complex-Variante für jede Zeile die Vektorschreibweise für complex zur Anzeige genutzt werden.

    Dann ist die View natürlich "enttemplatisiert", da die Datenbefüllung ja über einen Erben von QAbstractListModel stattfindet.

    Aber das verschiebt das Problem ja nur: Wie löse ich das Problem, dass QAbstractItemModel beide vector zur Anzeige gestattet?

    Variante 1 wäre z.B.:

    class VectorModelBase : public QAbstractListModel
    {
        // definiert alles, was sowohl für vector<int> als auch vector<complex> klappt
    };
    
    class IntVectorModel : public VectorModelBase
    {
        // implementiert Methoden entsprechend des int-Parameters anders
    };
    
    class ComplexVectorModel : public VectorModelBase
    {
        // implementiert Methoden entsprechend des complex-Parameters anders
    };
    

    Logischer erscheint mir aber doch Variante 2, durch die wir noch mehr in die Base stecken können:

    template<typename VectorT>
    class VectorModelBase : public QAbstractListModel
    {
        // wie oben, aber jetzt kann auch std::vector<VectorT>* ein Attribut sein (oder wenn wir Controller/Model zusammenlegen, meinetwegen auch ohne *)
        // Vorteil: In der obigen Variante haben wir immer noch viel Code doppelt, der einfach auf vector<T> zugreift,
        // obwohl T hier für mancherlei Zugriff egal ist (kombinierbar mit CRTP, keine Frage)
    };
    
    class IntVectorModel : public VectorModelBase<int>
    {
        // Doppelcode fällt heraus, nur vector<int>-spezifischer Code ist notwendig
    };
    
    class ComplexVectorModel : public VectorModelBase<complex>
    {
        // ibid.
    };
    

    Obiges Modell ist vereinfacht. Feedback dazu hilft mir mit hoher Wahrscheinlichkeit auch in meinem Fall weiter. 🙂

    Mein tatsächlicher Anwendungsfall ist jetzt nur insofern anders, dass ich View und Model (bzw. in einem strikteren Sinne imo Controller) nicht trenne, weil diese Trennung in meinen Augen nur dann Sinn ergibt, wenn man einen Controller für unterschiedliche Views nutzen möchte, was in meinem Fall ausgeschlossen erscheint (vll. bin ich zu kurzsichtig; und natürlich gibt es für meinen Fall von QT kein Model). Daher fällt der Template-Parameter eben direkt aufs View an und nicht auf ein dazwischen geschobenes Model.

    Kann man damit besser arbeiten? Auch die Frage meine ich ernst, da ich ja sehe, wie schwer meine Abstraktionen verständlich zu sein scheinen. 😞


  • Mod

    Also erstnoch mal die Bemerkung, dass Templates nicht mit dem Moc funktionieren, du könntest evtl mit einer Basisklasse Dinge vererben...

    ... ich bin aber der Meinung, das es viel besser ist für UI zu daten die hat-ein beziehung zu wählen, als die ist-ein.

    Zurück zum Model, die Schnittstelle mit der dort Datenabgefragt werden ist:

    QVariant data(const QModelIndex &index, int role) const
    

    index.row() wäre jetzt der Index von deinem vector. Index.column würde die Spalte angeben, hier wohl immer 0.
    Um hier in dein Backend sinnvoll zu kommen, würde ich obiges Interface etwas umbauen, und mit std/boost::function als Callback verwenden.
    Die Klasse auf die der Callback zeigt, kann dann in deinem Backend den richtigen String/Variant zurückgeben.



  • phlox81 schrieb:

    Also erstnoch mal die Bemerkung, dass Templates nicht mit dem Moc funktionieren, du könntest evtl mit einer Basisklasse Dinge vererben...

    Wobei der moc AFAIK nur notwendig ist, wenn die Klasse entweder signals/slots definiert oder übers meta object system von Qt angesprochen werden soll.



  • Ja, dass das so nicht geht, ist klar, dafür ja die Lösung im OP. Die Begründung für hat-ein statt ist-ein basiert auf den üblichen Daumenregeln dafür? Oder gibt es dafür im MVC-Umfeld noch ein paar zusätzliche Argumente? Im Grunde genommen hast Du aber schon Recht...

    Um hier in dein Backend sinnvoll zu kommen, würde ich obiges Interface etwas umbauen, und mit std/boost::function als Callback verwenden.

    Oh, darüber muss ich Mal nachdenken. Wenn das so funktioniert, ist der Vorteil, dass ich die Abhängigkeiten (ob Klasse->Klasse durch Beziehungen oder Template-Argumente) massiv minimiere, richtig?

    Wie löse ich jetzt Validierungsfunktionen, wenn man die Listenelemente abändern können soll? Da benötige ich ja ein neues std::function.

    Nächste Verkomplizierung:
    Im selben Dialogfenster werden die Daten über kommaseparierte Werte im QLineEdit dargestellt. D.h. für ein vector<int> erhalte ich z.B. "10,20,30,40" und für ein vector<complex> "(10,5),(20,7),(30,9)". Auch hier benötige ich dann ja zwei std::function (für Text aus Backend ziehen und Text validieren).

    Lässt sich Dein Vorgehen nicht irgendwie abstrahieren? Also nutzt Du grundsätzlich immer und überall std::function, wenn man es damit abbilden kann, sodass Du die Abhängigkeiten einfach so gering wie möglich hältst? Ich müsste an vielen Stellen, um mein eigentliches Verhalten zu simulieren, meistens 2 (wie oben dargestellt) oder sogar noch mehr std::function einbauen. Und irgendwie wirkt das auf mich dann immer gefrickelt, wobei der Vorteil durchaus ist, dass man die Abhängigkeiten gering hält.

    Es gibt doch sicher Schwellen, ab denen man bei x std::function-Objekten sagt: Ne, jetzt darf das Model auch Mal abhängig vom abzubildenden Typ sein, oder?



  • @Eisflamme: Wenn du die bestehenden Views von Qt verwenden und nicht einen komplett eigenen View bauen möchtest, kommst du um ein Model nicht herum. Die ganzen Views in Qt sind auf das Model-View Konzept ausgelegt.

    Ist die Darstellung in einem ListView readonly oder soll der Benutzer auch Werte Ändern können?

    Und wenn der Benutzer Werte ändern können soll? Wie soll die Eingabe aussehen?

    z.b. für dein Vector<int> variante soll der Benutzer beim editieren im View ein Textbox oder eine NumericTextbox (mit optional spinner controls) sehen?

    Wobei zweiteres zu bevorzugen wäre, weil du dann direkt wieder ein int vom view bekommst.

    Für die konkrete Darstellung in einem View (egal ob readonly oder im edit modus) sind in Qt sogennante delegates verantwortlich, welche einem View mitgegeben werden.

    Falls du das ganze Model-View konzept von Qt nicht kennen solltest, aus der Docu von Qt4 über Model-View: http://qt-project.org/doc/qt-4.8/modelview.html



  • Das Model-View-Konzept sowie Delegates sind mir bekannt. Leider beantwortet das nicht meine Fragen im vorherigen Post.

    Wie bereits mehrfach erwähnt und auch erläutert: Ob ich jetzt (wie in Deinem Link auch beschrieben) Model und View trenne oder der View die Daten innerhalb des Views verwendet, ändert überhaupt nichts an meinem Problem, wie ich die Abhängigkeiten zwischen View (oder Model) und meinem Backend gestalte. Trotzdem bin ich mittlerweile davon überzeugt, dass man sich dann eben für nicht-triviale Daten ein eigenes Model (QT-Terminologie) bauen sollte, da habt ihr ja Recht.

    Zudem gibt es für QLineEdit kein Model von QT, somit muss ich hier für eine konsequente Umsetzung ein eigenes schreiben.

    Ansonsten fände ich etwas stärkeren Bezug zu meinem letzten Beitrag super. 🙂

    Und wenn der Benutzer Werte ändern können soll? Wie soll die Eingabe aussehen?

    Ja, sind änderbar und zwar in Textform, weil die Zahlen ja wieder nur eine Vereinfachung sind und wir für den Spezialfall der Zahlen zwar jetzt eine etwas umständlichere Lösung hätten, die sich aber leichter auf mein eigentliches Szenario übertragen lassen.

    Die Frage, die sich hier stellt, wäre dann ja wieder: Darf der Delegate die Backend-Klassen wirklich kennen oder soll er auch wieder nur über std::function mit denen kontaktieren? (Änderbarkeit [=Validierung] + Auslesen erfordert dann zwei std::function; wird bei mir aber vermutlich wieder auf mehrere hinauslaufen)



  • Hab ich was falsch/zu wenig formuliert? Wenn ihr mir nicht antworten könnt, weil ich es nicht deutlich genug schreibe, gebt mir bitte darauf Rückmeldung.

    Die einzige Konsequenz aus dem Thread ist bisher für mich wieder, dass ich Zweifel an meinem Design habe, weil ihr es nicht schön findet/versteht... Aber gut, Abhängigkeiten geringer halten als ich es mit dem Template tue ist ja eine Grundrichtung, die ich verstehe. Ich werde selbst überlegen, ob es mit weniger Abhängigkeit geht - oder ob eben nicht.



  • Also für diesen Beitrag sag ich nochmal vorneweg, dass die QT-Models im MVC-Sinne ja eigentlich nur als Controller zu gebrauchen sind (siehe auch: http://stackoverflow.com/questions/5543198/why-qt-is-misusing-model-view-terminology )

    Tja, nächste Sache: Wenn ich die Modelklassen von QT nicht verwende(n kann), weil das jeweilige "View"-Objekt von QT (bzw. Widget, ist ja deren selbsternannte andere Klasse von Widgets) zu keinem Model passt (und setModel nicht anbietet), wie soll ich dann überhaupt eine Controller-Zwischenschicht erschaffen?

    Ich finde immer noch, dass bei View : Controller 1:1 es unnötig ist hier zu separieren, zumal wir das Problem haben, dass wir den Controller irgendwo speichertechnisch verwalten müssen. Möglich wäre:

    class LineEditView : public QLineEdit
    {
    public:
        // ctor
    
        void setModel(AbstractLineEditModel* model); // Eigenkreation
    };
    

    , wobei AbstractLineEditModel jetzt alle möglichen Slots anbietet. Somit kennt der View nur indirekt den Controller. Dass er dennoch die abstrakte Klasse kennt, finde ich jedoch etwas unschön, aber das wäre zumindest eine Variante. Und die Speicherverwaltung wäre damit auch abgedeckt, wenn LineEditView den Besitz übernimmt.

    Es erscheint somit sinnvoll bei 1:1 einfach z.B. ein VectorLineEdit (für meinen Fall) von QLineEdit erben zu lassen mit folgenden Vorteilen:
    - wir wissen, "wohin" mit VectorLineEdit, da es einfach als View-Objekt mit impliziertem Model erstellt wird
    - da der View in QT sein Model ohnehin besitzt (obwohl nicht die spezielle Klasse, wohl aber die abstrakte kennt), haben wir Laufzeit/Speicherverwaltung kongruent zu sonstigen QT-Views nebst -Models
    - Konkrete Nachteile konnte keiner benennen; die Nachteile, die ich sehe, liegen darin begründet, wenn man den Controller für einen anderen View nutzen könnte, was hier entfällt

    Somit haben wir eben QLineEdit bzw. den Erben, der View und Controller kombiniert. Für den könnte ich jetzt sogar noch drei std::function-Objekte nutzen. Die kombiniere ich dann aber doch besser als struct, die übergeben wird, ist flexibler, falls ich noch mehr brauche, oder?

    Das QLineEdit befindet sich aber im Dialog. Und von welchem Objekt ich die function-Objekte erstelle, hängt davon ab, was der Dialog erhält, da auch der nur kennend (nicht besitzend) mit einem vector<?>-Objekt verbunden ist und daher ein Template wäre.

    Oder ich übergebe die drei std::function-Objekte (bzw. die Struktur, s.o.) an den Dialog bereits. Im Dialog gibt es jedoch auch andere Views, welche den vector<?> nutzen (davon selbstgestaltete grafische Teile, die also auch kein QT-Model gebrauchen können) - auch dafür müsste ich dann std::function-Bulks mitliefern.

    Dafür spare ich mir beim Dialog den Templateparameter. Aber - was genau nützt mir das? Im Grunde soll der Dialog flexibel erweiterbar bleiben, er kennt nur die darzustellende Klasse und kann Views flexibel darauf aufbauen, was dort angezeigt werden soll. Möchte ich dort einen neuen Viewtyp hinzufügen, bräuchte ich also wieder einen neuen std::function-Bulk und somit würde jeder Nutzer des Dialogs wieder die ganzen std::function-Objekte basteln müssen. Das soll aber den Nutzer gar nicht interessieren, also da gehört es nicht hin.

    Wenn aber der Dialog template ist, könnte er wunderbar den Templatetypen an das Textfeld und die grafische Anzeige weitergeben, wenn er die ja eh hat. Dafür müssten die wieder template sein, finde ich aber eigentlich nicht so wild. Die werden eh niemals von jemandem genutzt, der als darzustellenden Typen etwas anderes angeben möchte.

    Somit erscheint die Lösung alles zu templatisieren hier am angebrachtesten, ich denke, das war jetzt auch nachvollziehbar argumentiert.



  • Eisflamme schrieb:

    Also für diesen Beitrag sag ich nochmal vorneweg, dass die QT-Models im MVC-Sinne ja eigentlich nur als Controller zu gebrauchen sind (siehe auch: http://stackoverflow.com/questions/5543198/why-qt-is-misusing-model-view-terminology )

    Wo siehst du in den Qt-Models (Abgeleitet von QAbstractItemModel) Controller Funktionalität?

    Ich sehe da keine. Die Models an sich stellen die Daten über eine definierte Schnittstelle bereit.

    In Qt ist es eher so, dass View und Controller oft(immer?) eine Entität darstellen.



  • Na ja, dafür der verlinkte Beitrag, dem ich nur 100% zustimmen kann: Der Witz an MVC ist, dass das Model unabhängig vom UI(-Framework) ist. Wenn QT mir aber das Model stellt, ist das eben nicht der Fall. Oder wie soll ich mein eigentliches Model jetzt noch in einer Konsolenanwendung oder als Basis für eine Handy-App wiederverwenden?

    Daher taugen die QT-Models nur dazu zwischen eigentlichem Model zu vermitteln. Wer aber zwischen Model und View vermittelt, wird üblicherweise Controller genannt. So ist die Terminologie logisch.

    Edit:
    Wobei, eigentlich ist es so auch nicht logisch. VCs sind schon irgendwie verschmolzen, je nachdem, wie man ein View halt definiert. Aber das, was als Model bezeichnet wird, ist dann eben ein Controller auf anderer Ebene. Oder man definiert Model wirklich so wie von QT, aber dann muss man zwangsläufig die Applikationslogik nochmal auf einen Bereich vor dem Model schieben, somit hätten wir also 4 "Arten von Komponenten". Denn zusätzlich zum M(V)C-Konzept von QT sollte man sein "eigentliches" Model/Backend imo als von QT unabhängigen Teil modellieren. Ich finde es unsauber (und man ärgert sich wie ich auch einfach), wenn man nicht einen auslagerbaren Teil QT-unabhängig entwickelt.

    Aber wie gesagt, verlinkter Beitrag argumentiert das ebenfalls. Ist ne Frage der Ebene, aber vermutlich gab es hier wegen meiner QT-unüblichen Beschreibung einige Missverständnisse.



  • klar kannst du auch Qt models in konsolen programmen verwenden...

    Und nur weil es auf stackoverflow was steht muss es nicht heißen dass es korrekt ist...

    Und Qt != Gui. Qt ist ein "komplettes" Application Framework wo die Gui nur ein kleiner Teil davon ist.

    Ich glaube so langsam trifften wir vom eigentlichen problem komplett ab...

    Und ich denke das wir aneinander vorbei reden, da auser dir vermutlich keiner weis was du eigentlich vor hast. Zu mindestens geht es mir so.

    Also beschreib bitte genau was du eigentlich vor hast. Und mir geht es dabei um das Prinzip/Idee.



  • Eisflamme schrieb:

    Der Witz an MVC ist, dass das Model unabhängig vom UI(-Framework) ist.

    Im Grunde ja. Aber das model muss eine wohl definierte Schnittstelle bieten, damit ein View oder Controller auch unabhängig einer konkreten model instanz/Implementierung funktionieren kann.

    Und wenn du verschiedene "Frameworks" mischt so bleibt es nicht aus, dass du Adapter Objekte erstellen musst.

    Und da Qt auch entsprechende Views bereitstellt, definiert es auch eine entsprechende Schnittstelle (in form von QAbstractItemModel).

    Eisflamme schrieb:

    Wenn QT mir aber das Model stellt, ist das eben nicht der Fall. Oder wie soll ich mein eigentliches Model jetzt noch in einer Konsolenanwendung oder als Basis für eine Handy-App wiederverwenden?

    Qt an sich stellt dir in erster Hinsicht nur eine definierte Schnittstelle bereit. Und die im Qtgui(qt4)/qtwidget(qt5) bereitgestellten Views verwenden diese Schnittstelle.

    Eisflamme schrieb:

    Daher taugen die QT-Models nur dazu zwischen eigentlichem Model zu vermitteln. Wer aber zwischen Model und View vermittelt, wird üblicherweise Controller genannt. So ist die Terminologie logisch.

    Sehe ich nicht so. Laut der Definition die ich kenne hat ein View lesenden zugriff auf das Model. Nur über den Controller können Änderungen am Model vorgenommen werden (z.b. um Input Validierung zu ermöglichen).
    Quellen:
    https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
    http://msdn.microsoft.com/en-us/library/ff649643.aspx

    Die Qt-Models (Abgeleitete Klassen von QAbstractItemModel) an sich sind Models. QAbstractItemModel definiert nur die Schnittstelle.

    In Qt sind View und Controller eine Entität. Und dadurch ist das Model-View Framework in Qt eher eine MVC Ausprägung namens ModelDelegate

    Eisflamme schrieb:

    Edit:
    Wobei, eigentlich ist es so auch nicht logisch. VCs sind schon irgendwie verschmolzen, je nachdem, wie man ein View halt definiert. Aber das, was als Model bezeichnet wird, ist dann eben ein Controller auf anderer Ebene. Oder man definiert Model wirklich so wie von QT, aber dann muss man zwangsläufig die Applikationslogik nochmal auf einen Bereich vor dem Model schieben, somit hätten wir also 4 "Arten von Komponenten". Denn zusätzlich zum M(V)C-Konzept von QT sollte man sein "eigentliches" Model/Backend imo als von QT unabhängigen Teil modellieren. Ich finde es unsauber (und man ärgert sich wie ich auch einfach), wenn man nicht einen auslagerbaren Teil QT-unabhängig entwickelt.

    Aber wie gesagt, verlinkter Beitrag argumentiert das ebenfalls. Ist ne Frage der Ebene, aber vermutlich gab es hier wegen meiner QT-unüblichen Beschreibung einige Missverständnisse.

    Ich denke auch das hier Missverständnisse auf beiden Seiten entstanden sind.

    Das Model-View Framework in Qt stellt ein paar Views bereit und definiert eine Grundlegende Schnittstelle über welche die Views mit einem Model kommunizieren können. Zusätzlich werden halt schon für ein paar oft genutzte Fälle konkrete Model Implementationen zusätzlich von Qt bereitgestellt.

    Wenn du bestehende Views von Qt (und damit sind nicht irgendwelche widgets gemeint) verwenden möchtest/musst, so musst du dich an die definierte Schnittstelle halten.

    Aber es spricht nichts dagegen im Backend komplett ohne Qt zu arbeiten. Wobei mit Qt 5.2 (mit 5.1 nur Android) auch komplette Smartphone Apps entwickelt werden können.



  • Okay, was Du so schreibst, ist alles in sich schlüssig und ich stimme einem großen Teil auch zu. Der einzige Unterschied ist: Wenn man bei QT den Modelteil wirklich als Model akzeptiert, impliziert das einige Dinge, denen ich widersprochen haben, weil das nach meiner Modeldefinition nicht korrekt ist.

    Aber meine Definition ist auch nur eine von vielen, ich bin da jetzt etwas offener und sehe schon, dass man das unterschiedlich definieren kann. Macht die Diskussion leider mühselig, aber die Literatur zum Thema ist ja nicht besser.

    Jedenfalls habe ich mein eigentliches Problem ja bereits gelöst. Wenn man so möchte, habe ich bei mir sogar MVC verschmolzen (was aber bei QT-Definition ohnehin für jedes Widget, welches nicht View/Model unterstützt der Fall ist), wobei mein eigentliches Backend (also QT-unabhängig, somit noch vor Model) eben Template ist.

    Möchte ich im QT-UI entsprechend die Templateklassen darstellen, dann sollte das Widget meiner Meinung nach auch template sein. Alternativvorschläge hier im Thread basieren ja nur auf std::function, was aber nur dann ginge, wenn meine Backend-Klassen so einfältig wären, dass dort nur Text gelesen und gesetzt würde.

    Tatsächlich werden über 5 verschiedene, je schreibende und lesende Methoden aufgerufen, was einfach eine Abhängigkeit vom Widget zu meinen Templateklassen als deutlich intuitiver erscheinen lässt. Kenntnis von Templateklassen erfordert aber eben, dass mein Widget selbst template wird. Und das ist auch völlig logisch und sauber in meinem Design.

    Kritik dazu nehme ich gerne mit sachlichen (und nicht für mich leider unnachvollziehbaren Erfahrungsargumenten) entgegen, aber anscheinend haben sich die meisten hier ja wie so oft ohnehin zurückgezogen, als ich die Schwachpunkte deren Lösungen oder Nachfragen Mal ins Feld geführt hab. 🙂

    Dennoch vielen Dank und beste Grüße!



  • Eisflamme schrieb:

    Tatsächlich werden über 5 verschiedene, je schreibende und lesende Methoden aufgerufen, was einfach eine Abhängigkeit vom Widget zu meinen Templateklassen als deutlich intuitiver erscheinen lässt. Kenntnis von Templateklassen erfordert aber eben, dass mein Widget selbst template wird.

    Das ein Widget auch ein template sein muss, da es ein Klassentemplate als member referenziert ist falsch. Es mag vielleicht deiner Meinung so sein.

    Da du meine Frage nicht beantwortet hast... hier noch einmal etwas abgewandelt:

    Wie genau sieht dein Model Konzeptionell aus?(keine konkrete Implementation)
    Und wie steht das UI-Element dazu in Beziehung?



  • @firefly: das seh ich anders. Die QAbstractItemModels von Qt sind für mich auch eher Controller. Das sind keine "Modelle". Ich werde meine Logik sicher nicht in Form von QAbstractItemModel definieren, wo ich über Indizes und QVariants auf die Daten zugreife. Das eigentliche Modell besteht aus stark typisierten Klassen, wie Person, AddressBook und was weiß ich was. Das wäre das Modell.
    Eine QAbstractItemModel Ableitung, die darauf zugreift, ist nur eine Zwischenschicht. Man kann darüber streiten, ob man sie als Modell oder Controller bezeichnet. Es wäre für mich aber sicher nicht das Modell in dem Sinne von MCV wenn man die gesamte Anwendung betrachtet. Vielleicht sowas wie das ViewModel beim MVVM von Microsoft. Ich seh aber auch kein Problem damit, das QAbstractItemModel als Controller zu bezeichnen.



  • @Eisflamme: ja, ich finds immer noch etwas schwierig, mir konkret vorzustellen, was du willst. Vielleicht kannst du mal ein einfaches Beispiel mit zwei konkreten Modell Klassen und der entsprechenden UI machen, wie du dir das vorstellt und was du da gemeinsam verwenden willst? Also, wirklich ein Beispiel wo man sieht, was die Klassen für Daten beinhalten und wie du die View wiederverwenden willst.
    Deinen Vergleich mit Policy Based Design kann ich nicht wirklich nachvollziehen. Beim Policy Based Design geht es meist um grundlegende Sachen, z.B. SmartPointer und Speicherverwaltung. Das ist etwas, was bei so gut wie jeder Klasse Sinn macht. Du hingegen willst die GUI über Templates für verschiedene Klassen wiederverwenden, und das ist etwas, was schon wieder sehr sehr selten zusammenpasst. Es würde mir wahrscheinlich echt schwerfallen, in unserer Software zwei Klassen zu finden, wo man das anwenden könnte.


Anmelden zum Antworten