Attribute und Einstellungen klassenübergreifend

Alles rund um die Programmierung mit Qt
Antworten
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Attribute und Einstellungen klassenübergreifend

Beitrag von Massimo B. »

Hallo.

Im #qt channel diskutieren wir seit einiger Zeit darüber:

Mein Fall: Ich habe ein Hauptfenster und ein Unterfenster child QDialog settings. Das Hauptfenster hat attribute wie host, port und eine Methode saveSettings(). Auch der QDialog settings möchte auf saveSettings() zugreifen, wie auch auf attribute host, port.
Auch wenn QDialog ein child vom Hauptfenster ist, kennt es nicht MainWindow::saveSettings().

Soll ich nun diese Elemente alle public machen?
  • Methoden für den Variablenzugriff wie getHost(), getPort() scheint mir zu aufwändig.
  • Attribute sollten ja nicht public sein.
  • friend class wäre eine Möglichkeit, wenn auch nicht ganz sauber.
  • Wie verknüpfe ich ein SIGNAL aus dem QDialog settings mit einer Methode des Hauptfensters?

    Code: Alles auswählen

    #include "settings.h"
    #include "qmobida.h"
    
    Settings::Settings(QWidget* parent, const char* name, bool modal, WFlags fl)
    		: SettingsBase(parent,name, modal,fl)
    {
    	connect( saveButton, SIGNAL(clicked()), &qMobida, SLOT(QMobida.fileSave_settings()) );
    Das Objekt des qMobida (Hauptfenster) kann aber gar nicht bekannt sein, da es in main() erstellt wird. main() kann ich doch nicht includen.
  • In saveSettings() wird ja QSettings verwendet. Nun gibt es Leute die QSettings gerne "missbrauchen", um klassenübergreifend Daten zu verwenden. Eigentlich ist das ok, wahrscheinlich wird der Zugriff sogar gecached und läuft nicht direkt über Dateizugriff.
  • Nachteil: Ich möchte Werte wie host, port auch mal temporär setzen. QSettings::writeEntry() läuft aber direkt in die Datei. Abhilfe wäre z.B. 2 QSettings Gruppen oder Dateien zu verwalten für temporär und permanent.
  • In jedem Fall muß QSettings settings im ganzen Programm mitgeführt und die Gruppe offengehalten werden. Bisher war das nur innerhalb der Methode writeSettings() nötig.
Gentoo (x86,ppc), KDevelop, Qt3, Qt4
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Beitrag von Massimo B. »

Weitere Möglichkeit wäre eine Objekt SettingsData sData; , das alle Einstellungen enthält und an die Unterklassen mitgegeben wird.

Code: Alles auswählen

#include <qstring.h>

class SettingsData
{
	public:
		SettingsData();
		~SettingsData();
		
		QString host;
		Q_UINT16 port;
};
Dieses müßte aber doch auch alle Werte als public besitzen, oder?
Gentoo (x86,ppc), KDevelop, Qt3, Qt4
Esleborn
Beiträge: 265
Registriert: 27. Januar 2005 01:23
Wohnort: Baden-Würtenberg
Kontaktdaten:

Beitrag von Esleborn »

paoleela hat geschrieben:Dieses müßte aber doch auch alle Werte als public besitzen, oder?
naja... ich würd ja eher über Funktionen darauf zugreifen, ist einfach eine schönere Schnittstelle... (und wenn alles public Elemente sind, würde ich eine struct vorschlagen...)

Was spricht gegen einen namespace in dem die benötigten Funktionen statisch gegeben werden, und der per Zeiger das Hauptfenster speichert? Dann hast du eine schöne Trennung zwischen Hauptfenster und Dialog, kannst beide unabhängig weiterbauen (auch ohne includen der Hauptfensterdeklaration oder so nen Schmarn) und könntest später auch auf ein QSettings oder ähnliches umsteigen.
Natürlich könntest du das Hauptfenster auch dynamisch suchen lassen (QApplication::findChild < TypDeinesHauptfenster > ( ) falls es dort child ist, oder QApplication::activeWindow ( ) [ich weiß nicht ob das evtl. den Dialog zurückgibt] bzw allWidgets ( ) jeweils mit anschließend qobject_cast < TypDeinesHauptfenster > ( gefundenesChild ) )...
Glaube an eine Lösung, nur dann kannst du auch eine finden.
Esleborn
Beiträge: 265
Registriert: 27. Januar 2005 01:23
Wohnort: Baden-Würtenberg
Kontaktdaten:

Re: Attribute und Einstellungen klassenübergreifend

Beitrag von Esleborn »

paoleela hat geschrieben:[...]Soll ich nun diese Elemente alle public machen?[...]
Nein, wenn dann per Funktionen drauf zugreifen, ist sauberer.
paoleela hat geschrieben:[...]Methoden für den Variablenzugriff wie getHost(), getPort() scheint mir zu aufwändig.
??? Zu Aufwendig?
paoleela hat geschrieben:[...]Wie verknüpfe ich ein SIGNAL aus dem QDialog settings mit einer Methode des Hauptfensters?

direkt nach dem du den child-Dialog (p_dialog) konstruiert hast (falls innderhalb einer Funktion des mainWindow, sonst musst du eben this durch den entsprechenden Zeiger ersetzen):

Code: Alles auswählen

connect ( p_dialog, SIGNAL ( saveSettings ( ) ), this, SLOT ( saveSettings() ) );
dann muss saveSettings nur (mindestens) ein privat slots sein.
paoleela hat geschrieben:[...]

Code: Alles auswählen

#include "settings.h"
#include "qmobida.h"

Settings::Settings(QWidget* parent, const char* name, bool modal, WFlags fl)
		: SettingsBase(parent,name, modal,fl)
{
	connect( saveButton, SIGNAL(clicked()), &qMobida, SLOT(QMobida.fileSave_settings()) );
Das Objekt des qMobida (Hauptfenster) kann aber gar nicht bekannt sein, da es in main() erstellt wird. main() kann ich doch nicht includen.
ähh bin ich doof, oder müsste es nicht mal? (Ich gehe davon aus, dass der parent, dass MainWindow ist)

Code: Alles auswählen

connect ( saveButton, SIGNAL(clicked()), parent, SLOT(fileSave_settings()) );
paoleela hat geschrieben:[...]Eigentlich ist das ok, wahrscheinlich wird der Zugriff sogar gecached und läuft nicht direkt über Dateizugriff.
korrekt

Bin ich restlos doof, hilft dir das nichts, oder hat das weitergeholen?


Elgrimm Esleborn
Glaube an eine Lösung, nur dann kannst du auch eine finden.
Massimo B.
Beiträge: 45
Registriert: 14. Juni 2006 11:05
Wohnort: Bonn, Germany

Re: Attribute und Einstellungen klassenübergreifend

Beitrag von Massimo B. »

Esleborn hat geschrieben:
paoleela hat geschrieben:[...]Soll ich nun diese Elemente alle public machen?[...]
Nein, wenn dann per Funktionen drauf zugreifen, ist sauberer.
Ich hab mich für eine eigene Klasse entschieden, welche alle Attribute public enthält, und ihrerseits bei Bedarf QSettings zum Speichern nimmt. "Aufwändig" war vielleicht falsch formuliert. Ich sehe nur nicht den Sinn Schnittstellen für jedes Attribut einzurichten bei einer Klasse, die eigentlich auch nur diese Attribute enthält.
Esleborn hat geschrieben:
paoleela hat geschrieben:[...]Wie verknüpfe ich ein SIGNAL aus dem QDialog settings mit einer Methode des Hauptfensters?
direkt nach dem du den child-Dialog (p_dialog) konstruiert hast (falls innderhalb einer Funktion des mainWindow, sonst musst du eben this durch den entsprechenden Zeiger ersetzen):

Code: Alles auswählen

connect ( p_dialog, SIGNAL ( saveSettings ( ) ), this, SLOT ( saveSettings() ) );
dann muss saveSettings nur (mindestens) ein privat slots sein.
Das Signal kommt aber im child-Fenster, während der Slot im parent-Fenster liegen soll.
Ich hab das nach Tips in #qt elegant mit Signal-Pipelining gelöst. Im child-Fenster wird das Signal auf ein neues Signal verlinkt, das dann im parent-Fenster vom Sender abgeholt wird:

Code: Alles auswählen

connect( saveButton, SIGNAL(clicked()), this, SIGNAL(saveClicked()) );
Esleborn hat geschrieben:
paoleela hat geschrieben:[...]Eigentlich ist das ok, wahrscheinlich wird der Zugriff sogar gecached und läuft nicht direkt über Dateizugriff.
korrekt
Bin ich restlos doof, hilft dir das nichts, oder hat das weitergeholen?Elgrimm Esleborn
Es ist eine Möglichkeit, aber siehe ^Nachteile. Ausserdem müßte es eine Cpp Strategie geben, um Daten zwischen Klassen auszutauschen. Denke mal, das mit der Attributklasse ist nicht schlecht. Sie wird Attribut des parent-Fensters sein, und den child-Klassen per Referenz mitgegeben.
Gentoo (x86,ppc), KDevelop, Qt3, Qt4
Antworten