Verantwortlichkeits-Problem
-
Also ich finde auch nicht, dass das Textfeld einen Dialog oeffnen sollte. Vorallem muss ich das Textfeld um einen Slot ueber Vererbung erweitern. Wieso kann der Button den Dialog nicht oeffnen und wieso kommt das Textfeld nicht ans Main-Widget ueber parent?
Btw. Signale, Textfelder, Dialoge ... kenn C++11 noch nicht. Schreib doch das GUI-Toolkit dazu. Und ich benutze bestimmt ein anderes GUI-Toolkit als du, wo es solche Probleme nicht gibt.
-
Das heißt man kann in QT einem "event" keinen Funktor andrehen, nur einen slot AKA Member-Function-Pointer? Ich kenne mich ja überhaupt nicht mit QT aus, daher kann ich nur im Trüben fischen. Wenn das der Fall ist, dann ist das was Du zuletzt schilderst wohl genau das, was für QT-Entwicklung so vorgesehen ist.
Fänd ich jetzt aber auch relativ schwach.
So oder so wirst Du aber im Hauptfenster entweder das bind zusammenschnüren, oder das eben im Slot erledigen. Beides führt ja zu ähnlich viel Code. Nachteil ist nur, dass Du eben das (wahrscheinlich private) Interface aufblähen musst. Daher würde ich persönlich die bind-Variante bevorzugen, aber wenn das halt nicht geht...
-
knivil:
Na ja, boost kennt signals. Aber ich benutze in dem Fall QT.Nachteil ist nur, dass Du eben das (wahrscheinlich private) Interface aufblähen musst.
Genau, das ist mein Problem.
Das heißt man kann in QT einem "event" keinen Funktor andrehen, nur einen slot AKA Member-Function-Pointer?
Member-Function ist doch eine Methode? Also ich glaube, dass Slots nur innerhalb von Objekten funktionieren. Klar kann ich auch ein Paket schnüren, aber das muss dann ja der Button auch haben, um es dem Dialog zu übergeben, wenn irgendein Slot aufgerufen werden muss. Also das läuft für mich auch aufs selbe hinaus irgendwie.
-
Also folgender Vorschlag.
Wenn Buttons so erstmal nur Slots unterstützen, die nur "Methoden" sein können, dann würde ich mir einen Button ableiten, der std::function als Handler unterstützt, anstatt, oder zusätzlich zu den slots.
Dann würde ich diesen Button verwenden und dort im Haupfenster mit std::bind einen Handler schnüren.
-
decimad schrieb:
Also folgender Vorschlag.
Wenn Buttons so erstmal nur Slots unterstützen, die nur "Methoden" sein können, dann würde ich mir einen Button ableiten, der std::function als Handler unterstützt, anstatt, oder zusätzlich zu den slots.
Dann würde ich diesen Button verwenden und dort im Haupfenster mit std::bind einen Handler schnüren.Er kann auch Qt5 verwenden, dort hat sich die connect syntax erweitert.
Nun können zu signals auch lambdas oder std::function objekte gebindet werden.
http://qt-project.org/wiki/New_Signal_Slot_Syntax
-
Umso besser, danke für die Info! Ansonsten wäre Qt schon von vornherein ausgefallen für mich.
-
Ok, das würde konkret heißen, dass ich vermutlich über Lambda-Ausdrücke im Hauptfenster diese Funktionszeiger-Objekte basteln würde, die ich dann via connect an den jeweiligen Button übergebe.
Gespart habe ich an Code also wenig, nur die Headerdatei der Hauptfenster-Klasse zeigt weniger Methodendeklarationen.
Würdet ihr das dann also wirklich so machen oder ist das nur der Vorschlag basierend auf meiner Idee, dass man den Klassenheader entschlacken möchte?
-
Da müsste man sich mal zurücklehnen und sich fragen, inwiefern es Sinn macht, interne Implementierungsdetails in die Klassendefinition zu verfrachten. Das macht man ja nun eigentlich ständig und wirkt dann irgendwann mit pImpl-Muster entgegen. Im Prinzip ist das ja dieselbe Situation.
Aber viel wichtiger war ja der Punkt, dass das Edit-Feld am besten keine Verantwortlichkeit für den Ablauf Deines Programmes übernehmen soll. Ich schließe den Wasserhahn ja auch direkt an die Wasserleitungen an und verlege ihn nicht durch die Kaffeemaschine (Hab eben gerade Kaffee geholt ;)).
Code sparen kannst Du Dir eigentlich bei einem Einmal-Auftreten überhaupt nicht. Erst wenn Du viele Dialoge mit ähnlichen Anforderungen hast, könnte es vielleicht Sinn ergeben, sich eine Kontext-Klasse zu schreiben, die man eben wiederverwenden kann.
-
Ich weiß aber auch nicht, inwiefern Dein "Hauptfenster" schon das Datenmodell selber ist, auf dem gewerkelt wird, oder ob Du eine von der GUI total unabhängige Kapselung Deiner Daten hast, und das Hauptfenster da nur eine Referenz zu hält. Von alledem ist da die Einschätzung ja abhängig.
-
Na ja, es läuft eben alles über das Hauptfenster. Das instanziiert eben die Klassen, welche zum Datenmodell gehören und welche auch global benötigt werden. Ansonsten instanziiert jedes "Unterfenster" (also z.B. Tabs oder auch Dialoge) das, was dafür jeweils notwendig ist. Irgendwo muss ich es ja instanziieren. Das könnte ich natürlich auch mit globalen Variablen bewerkstelligen, aber so ist es schon logisch, weil es bei mehreren Hauptfenstern (auch wenn das zurzeit kein Anwendungsfall ist) so ebenso funktionieren würde, was auch logisch erscheint.
-
Ja naja, dann ist es echt geschmackssaache ob Du einen slot hernimmst oder ein Lambda verwendest. Ich denke die meisten QT-Coder würden wahrscheinlich einen slot erwarten, wohingegen die meisten C++11-Coder ein Lambda als den letzten Schrei betrachten würden.
Wichtig ist nur, dass der Dialog keine Referenz auf das Hauptfenster verlangt, sondern eine Referenz auf *irendein* Fenster (halt als Parent) und ansonsten nur auf auf die Elemente des Datenmodells (falls Du nicht sowieso schon eine große Kapselungsklasse für die einzelnen Elemente des Datenmodells hast, dann darauf).
So kann man das ohne Probleme auf eine MDI-Anwendung umstricken.
-
Klar, wieso sollte der Dialog das Hauptfenster kennen?
Nagut, dann ist es wohl einfach wirklich egal. Irgendwie finde ich hier keine Lösung schön, auch mit Lambda und QT5 nicht... ich muss wohl mein Ästhetik-Empfinden bzgl. UI-Code neu eichen...
-
Was findest Du denn jetzt eigentlich unschön, ich kann Dir da nicht folgen? Wir haben doch eine Möglichkeit herausgearbeitet, die ohne Anpassung der Klassenschnittstelle auskommt, was ja zuerst Dein Anliegen war.
Der Rest der Unschönheit zieht sich durch das gesamte Programmiererleben und findet in der unglaublichen Popularität von globalen Variablen seine Entsprechung: "Wie komme ich von hier an die Daten ran, ohne was tun zu müssen?!". Das ist ja kein Problem, das auf GUI-Projekte beschränkt bliebe.
-
Und ich möchte Dir natürlich Deine Meinung lassen, nur kenne ich aus leidlicher Erfahrung, dass Programmieren aufhört Spaß zu machen, wenn man zunehmend an dem, was man da tut, zweifelt. Dann ist es am besten, wenn man sich die Zeit nimmt und darüber nachdenkt, warum man zweifelt und am besten am Ende zu der Einsicht kommen, dass das abstrakte Problem nunmal so ist und dass es nichts damit zu tun hat, dass man die falsche Programmiersprache verwendet oder überhaupt alles doof ist ;). Oder aber man findet DIE Lösung schlechthin, die dann in C++ aber meist wieder nach hinten losgeht
