Trennung von Logik und UI

8

Ich entwickle eine GUI-Anwendung in Qt.

Dies ist meine erste GUI-Anwendung und ich bin nicht sehr erfahren und muss immer noch mit einigen fortgeschritteneren Aspekten von C ++ und Qt-Framework ringen.

Die Anwendung ist ziemlich einfach, mit einem Hauptfenster und einigen Dialogen, in denen der Benutzer Einstellungen vornimmt und eine Taste drückt, und das Programm führt eine (ziemlich komplexe) Berechnung durch und gibt das Ergebnis irgendwo auf der Benutzeroberfläche aus.

Jetzt habe ich ein Problem. Ich lege alle meine Berechnungsdaten (die statisch sind und von Ressourcen geladen werden) und Logik in eine separate Klasse. Ich erstelle eine Instanz dieser Klasse und der UI-Klassen. Nun besteht das Problem darin, wie man von einer UI-Klasse auf die Mitglieder der Daten- / Logikklasse zugreifen kann. Angenommen, es gibt eine QStringList in der Logic-Klasse und ich möchte einen bestimmten Dialog, um auf diese Liste zuzugreifen und sie dem Benutzer zu präsentieren, ohne Kopien davon im Speicher zu erstellen?

Ich verstehe, dass dies wahrscheinlich eine sehr einfache C ++ - Frage ist (Qt nicht einmal relevant), aber hey nicht jeder ist ein Programmier-Assistent. Danke für einen Hinweis oder Hilfe!

    
vedran 13.08.2011, 14:56
quelle

3 Antworten

12

Es gibt mehrere Möglichkeiten, dies zu tun, damit Ihre Frage gültig ist.

  1. Ihre GUI-Klasse kann von Ihrer Logic-Klasse abgeleitet werden. Nicht der typische Ansatz, aber es hängt davon ab, wie Ihre Anwendung konzipiert ist. Ein großer Nachteil ist, dass die GUI im selben Thread wie die Logik bleiben muss. Oft möchten Sie, dass die Klassen in mehreren Threads ausgeführt werden, so dass die GUI durch die umfangreiche Berechnung nicht eingefroren wird.

  2. Ihre GUI-Klasse kann einen Zeiger auf Ihre logische Klasse und / oder umgekehrt enthalten. Es kann auch eine Referenz für die Bequemlichkeit sein, wenn Ihre Logikklasse vor der GUI-Klasse existiert und sie überlebt. Dann können Sie den Verweis auf den Konstruktor der GUI-Klasse übergeben und Sie müssen nie testen, ob ein Zeiger gültig ist.

  3. Ihre GUI-Klasse kann über Getter / Setter oder direkt auf Datenmitglieder zugreifen, wenn Sie sie veröffentlichen möchten, oder einfach Ihre GUI-Klasse als friend -Klasse für die Logic-Klasse definieren. Auch wenn Sie Getter verwenden, können sie Const Referenzen zurückgeben, also keine Kopie beteiligt. Qt-Klassen wie QStringList haben auch ihren eigenen Reference-Counting-, Copy-on-Write-Mechanismus, der Kopien vermeidet.

  4. Ihre GUI-Klasse kann Signale aussenden und die Logic-Klasse kann sie empfangen. Siehe Qt-Signal / Slot-Mechanismus. Es ist sehr schön für Ereignisse wie eine Schaltfläche "Berechnung starten". Signale haben zwei Vorteile: (a) Sie können über Threads gehen, aber wenn der Empfänger nicht die Hauptschleife ist, wird es ein bisschen komplizierter; (b) Die Objekte müssen sich nicht sehen lassen (kein Zeiger passiert), Sie können die Signale an Steckplätze überall in Ihrem Programm anschließen, wo Sie beide Objekte gleichzeitig gesehen haben.

Normalerweise verwenden Sie eine Mischung aus 2 und 3: Verwenden Sie Getter, um die Daten aus der Logikklasse zu lesen, die dem Benutzer präsentiert wird. Verwenden Sie Signale, um eine Aktion zu provozieren oder Daten zu manipulieren (der Benutzer trifft eine Auswahl, die Logikklasse muss reagieren).

    
ypnos 13.08.2011, 15:29
quelle
4

Es gibt ein Programmiermodell namens MVC (Model - View - Control)

Für einfache Fälle reicht nur Model - View. Model repräsentiert Daten und View repräsentiert UI.

Die Model-Klasse stellt einige Schnittstellen zur Verfügung, die Daten setzen / abrufen. Die Modellklasse hat normalerweise keine Kenntnisse über die View-Klasse, aber normalerweise kann sie die View-Klasse benachrichtigen, wenn sich die Daten ändern (dies kann mit dem Signal / Slot in Qt geschehen).

Die View-Klasse enthält einen Zeiger auf die Model-Klasse und verwendet die Schnittstellen Model-Klasse, um die Daten zu bearbeiten.

    
Bood 13.08.2011 15:37
quelle
1

Vielleicht verpasse ich hier etwas, aber injiziere einfach deine Datenklasse über einen Setter in die UI-Klasse und zeige die Methode der Datenklasse als öffentlich an. Sie müssen nur einen Zeiger auf Ihre Datenklasse übergeben, um einen Coping-Overhead zu vermeiden.

    
Andrew White 13.08.2011 15:18
quelle

Tags und Links