Wie würdet ihr das machen...
Wie würdet ihr das machen...
Hi @ll,
bin gerade dabei einen Settingsdialog zu schreiben(bei OK soll die Settingsdatei geschrieben werden).... Ich will aber nicht jedesmal alles schreiben-also dachte ich mir ich mache mir eine Liste mit QObjects und packe da jedes Element rein welches sich verändert hat.
Beim "Übernehmen" will ich dann die Liste mit den Objects durchgehen und die Werte schreiben.
Aber wie Ordne ich die Werte am geschicktesten den Keys zu?
Freue mich über Ideen und Kritik!
bin gerade dabei einen Settingsdialog zu schreiben(bei OK soll die Settingsdatei geschrieben werden).... Ich will aber nicht jedesmal alles schreiben-also dachte ich mir ich mache mir eine Liste mit QObjects und packe da jedes Element rein welches sich verändert hat.
Beim "Übernehmen" will ich dann die Liste mit den Objects durchgehen und die Werte schreiben.
Aber wie Ordne ich die Werte am geschicktesten den Keys zu?
Freue mich über Ideen und Kritik!
Hi, also erstmal würde ich das lesen/schreiben der Einstellungen nicht von einem Widget/Dialog abhängig machen.
Da man Einstellungen ja meist an mehreren verschiedenen Orten im Programm braucht, macht sich hier ein Singleton ganz gut.
Ansatz:
Damit schreibst Du dann über die Setter die Werte wieder zurück. Wie und wo Du das dann in der GUI verbaust bleibt Dir überlassen... 
Da man Einstellungen ja meist an mehreren verschiedenen Orten im Programm braucht, macht sich hier ein Singleton ganz gut.
Ansatz:
Code: Alles auswählen
class GlobalConfig
{
public:
static GlobalConfig *getInstance();
void setAccount( const QString &email, const QString &password );
const QString &email() const { return m_email; }
const QString &password() const { return m_password; }
private:
GlobalConfig();
static GlobalConfig *s_pInstance;
QString m_email;
QString m_password;
};Code: Alles auswählen
GlobalConfig *GlobalConfig::s_pInstance = 0;
GlobalConfig *GlobalConfig::getInstance()
{
if( !s_pInstance )
{
s_pInstance = new GlobalConfig();
}
return s_pInstance;
}
GlobalConfig::GlobalConfig()
{
#ifdef Q_OS_WIN32
QSettings settings( QSettings::IniFormat, QSettings::UserScope, __COMPANY__, __APPLICATION__ );
#else
QSettings settings( QSettings::NativeFormat, QSettings::UserScope, __COMPANY__, __APPLICATION__ );
#endif
settings.beginGroup( "account" );
m_email = settings.value( "email", QString() ).toString();
m_password = settings.value( "password", QString() ).toString();
settings.endGroup();
}
void GlobalConfig::setAccount( const QString &email, const QString &password )
{
m_email = email;
m_password = password;
#ifdef Q_OS_WIN32
QSettings settings( QSettings::IniFormat, QSettings::UserScope, __COMPANY__, __APPLICATION__ );
#else
QSettings settings( QSettings::NativeFormat, QSettings::UserScope, __COMPANY__, __APPLICATION__ );
#endif
settings.beginGroup( "account" );
settings.setValue( "email", m_email );
settings.setValue( "password", m_password );
settings.endGroup();
}Genauso habe ich das schon.... also ein property mit hasChanged, und im nächsten noch den Key für das Settingsfile...
Bleibt nur noch die Frage wie man das dann mit dem Wert macht....
Wie kann man gescheit den Key speichern - ich weiß ja nicht was ich bekomme!
Bleibt nur noch die Frage wie man das dann mit dem Wert macht....
Code: Alles auswählen
foreach (QObject *obj, this->findChildren<QObject *>())
if (obj->property("hasChanged").toBool())
{
IniFile::getInstance().writeValue("Settings", obj->property(KeyName), "???");
}
Re: Wie würdet ihr das machen...
FailAuE hat geschrieben:bin gerade dabei einen Settingsdialog zu schreiben(bei OK soll die Settingsdatei geschrieben werden).... Ich will aber nicht jedesmal alles schreiben
Eine Datei wird sowieso immer komplett geschrieben. Da kannst du nix dran drehen. Eine Datei ist eine Bytefolge auf der Platte. Wenn du da einzelne Sachen neuschreibst, und die Länge nicht passt hast du Löcher oder überschreibst Bereiche die nicht zu deiner Datei gehören.
Das Einzige was du machen könntest, ist das Schreiben mit nem Timer zu steuern. Gib dir nen bool changed und nen Timer configWriteTimer. setz den Timer auf (von mir aus) 10 Minuten. wenn sich die Settings ändern (changed == true) wirst du bei Ablauf des Timers die Datei schreiben, ansonsten auf den nächsten Timer warten.
Aber nur wenn du ein bisschen die Schreibintervalle auf deine Platte zügeln willst.
??? wie jetzt du willst mir sagen das wenn ich nen QSettings Objekt habe das auf ein File zugreift .... das wenn ich dann nicht jeden wert mit setValue setze das dann Löcher entstehen??
Ich möchte dich nur die Werte setzen via QSettings.setValue oder auch andere routinen/libs die dann die geg. Werte schreiben.
Das heisst ich muss irgendwie an den Objekttypen rankommen....das heisst entweder casten oder als property speichern
Ich möchte dich nur die Werte setzen via QSettings.setValue oder auch andere routinen/libs die dann die geg. Werte schreiben.
Das heisst ich muss irgendwie an den Objekttypen rankommen....das heisst entweder casten oder als property speichern
Nein. Aus deiner Beschreibung ging für mich eindeutig hervor, dass du den jeweiligen Status einer Settings-Variable auf "changed" überprüfen können willst, um diesen dann einzeln in die Datei zu schreiben ("Ich will aber nicht jedesmal alles schreiben").AuE hat geschrieben:??? wie jetzt du willst mir sagen das wenn ich nen QSettings Objekt habe das auf ein File zugreift .... das wenn ich dann nicht jeden wert mit setValue setze das dann Löcher entstehen??
Und das geht einfach nicht! Entweder wird die ganze Datei geschrieben, oder eben nicht
Nein.... sry das es falsch rüberkam....
Ich habe nen Einstellungsfenster.... wenn der Nutzer dann mit OK rausgeht will ich jedes QObject fragen ob es ein Property hat das hasChanged heisst. Wenn dieses auf true ist so möchte ich via QSettings das ins Settingsfile übernehmen!
Nur fehlt mir halt noch die Idee wie ich aus dem qobject was ich habe herausbekomme wie ich an die Daten komme....
Ich habe nen Einstellungsfenster.... wenn der Nutzer dann mit OK rausgeht will ich jedes QObject fragen ob es ein Property hat das hasChanged heisst. Wenn dieses auf true ist so möchte ich via QSettings das ins Settingsfile übernehmen!
Nur fehlt mir halt noch die Idee wie ich aus dem qobject was ich habe herausbekomme wie ich an die Daten komme....
Re: Wie würdet ihr das machen...
Naja, QSettings schreibt ja nicht immer in ne Datei, unter Windows wird z.B. standardmäßig in die Registry im RAM geschrieben, und auch sonst wird der Schreibzugriff gepuffert, das Schreiben sollte also keine größeren Probleme machen.franzf hat geschrieben:Eine Datei wird sowieso immer komplett geschrieben. Da kannst du nix dran drehen. Eine Datei ist eine Bytefolge auf der Platte. Wenn du da einzelne Sachen neuschreibst, und die Länge nicht passt hast du Löcher oder überschreibst Bereiche die nicht zu deiner Datei gehören.
Zum eigentlichen Problem: Mach doch ne QMap oder nen QHash aus QString und QVariant, in den du einfach alles was sich ändert schreibst. sprich ändert sich "lala" auf den Wert 5 machst du einfach ein myHash.insert("lala", 5) und wenn dann geschrieben werden soll kannst du einfach den ganzen Hash mit Iterators durchgehen, abarbeiten und leeren. Somit hättest du deinen eigenen kleinen Cache, aber da QSettings, wie bereits gesagt, nen eigenen Cache verwendet weiß ich nicht ob dir das wirklich was bringt...
mfg N¤X
AuE hat geschrieben:Nein.... sry das es falsch rüberkam....
Ich habe nen Einstellungsfenster.... wenn der Nutzer dann mit OK rausgeht will ich jedes QObject fragen ob es ein Property hat das hasChanged heisst. Wenn dieses auf true ist so möchte ich via QSettings das ins Settingsfile übernehmen!
Nur fehlt mir halt noch die Idee wie ich aus dem qobject was ich habe herausbekomme wie ich an die Daten komme....
Code: Alles auswählen
for (...)
{
QComboBox* box = qobject_cast<QComboBox*>(obj);
if (box)
{
...
continue;
}
QLineEdit* line = qobject_cast<QLineEdit*>(obj);
if (line)
{
...
continue;
}
QSpinBox* spin = qobject_cast<QSpinBox*>(obj);
if (spin)
{
...
continue;
}
QDateTimeEdit* date = qobject_cast<QDateTimeEdit*>(obj);
if (date)
{
...
continue;
}
QTextEdit* text = qobject_cast<QTextEdit*>(obj);
if (text)
{
...
continue;
}
QCheckBox* check = qobject_cast<QCheckBox*>(obj);
if (check)
{
...
continue;
}
QDoubleSpinBox* doubleSpin = qobject_cast<QDoubleSpinBox*>(obj);
if (doubleSpin)
{
...
continue;
}
Re: Wie würdet ihr das machen...
Er hat ja explizit "Settingsdatei" geschrieben, drum bin ich davon ausgegangen ist ist tatsächlich eine Datei und hab nicht weiter über die Existenz anderer komischer Betriebssysteme nachgedachtN¤X hat geschrieben:Naja, QSettings schreibt ja nicht immer in ne Datei, unter Windows wird z.B. standardmäßig in die Registry im RAM geschrieben, und auch sonst wird der Schreibzugriff gepuffert, das Schreiben sollte also keine größeren Probleme machen.
Um welches Property geht es dir denn dann genau? Z.B. den "text" in nem LineEdit? "value" in ner SpinBox?wenn der Nutzer dann mit OK rausgeht will ich jedes QObject fragen ob es ein Property hat das hasChanged heisst. Wenn dieses auf true ist so möchte ich via QSettings das ins Settingsfile übernehmen!
Du kannst einfach bei jedem Objekt die üblichen Verdächtigen abfragen. Ob ein Property existiert bekommst du über
Code: Alles auswählen
obj->metaObject()->indexOfProperty(propertyName) != -1Was macht das unterscheiden nach der Plattform an der Stelle fuern Sinn ?#ifdef Q_OS_WIN32
QSettings settings( QSettings::IniFormat, QSettings::UserScope, __COMPANY__, __APPLICATION__ );
#else
QSettings settings( QSettings::NativeFormat, QSettings::UserScope, __COMPANY__, __APPLICATION__ );
#endif
Schreibt der Mac ned auch "nativ" in inni-files ?
also ein
QSettings settings(QSettings::IniFormat,QSettings::UserScope,_COMPANY__, __APPLICATION__ );
ohne die compiler schalter haette die selbe Wirkung, zumindest bei Windows, Linux, MacOS ?
Und warum sollten andere BS Ihre nativ formate verwenden dürfen und das arme windows ned ? ^^
Also wennscho dann konsequent ! ^^
Aber zurueck zum Topic:
Ich hab scho mehrere Strategien implementiert (implementieren müssen). Ich denk so pauschal kann man das ned beantworten, was gut iss und was ned.
Vorher solltest fuer Dich folgene fragen klaeren:
- wann koennen/sollen die Settings geholt werden, schon bei Start der App, oder erst wenn der zugehörige wert abgefragt wird/bearbeitet wird
- schreiben andere Apps auch auf die Settings und wenn ja, musst du die aenderungen die die machen mitbekommen ?
- wie schnell brauchst du die settings bei bedarf ... kannst dir ne fileoperation beim ersten aufrufen erlauben oder nich ?
- wenn deine App crasht, isses dann tragisch wenn gecashte aenderungen an den settings ned zurueckgeschrieben wurden ?
- Sind deine controls die Du verwendest, in der Lage den resultierenden Wert fuer die Settings zu halten, oder brauchst du soweiso ne Schicht zwischen die dir dieSettings fuer die anzeige / Bearbeitung aufbereitet ....
Denk aus den Antworten die Dir gibts, solltes Deine Strategie ableiten ... denk nich das es eine generelle tolle gibt, die bei alllen Fällen einsetzbar iss.
Ciao ...
Hi,
thx so far!
Also es handlet sich <aktueller Ansatz> um die Standard Qt Elemente wie Combobox, lineEdit, Slider, etc pp.
Mein jetziger Ansatz sieht wie folgt aus:
- hinzufügen der Propertys für (Changed, KeyName, Type)
- beim verlassen die Liste der Objects holen
- aus der Liste wie franzf gesagt hat schauen ob es das property "value" [..] gibt
- dieses dann via einer lib in das Settings-File eintragen
Andere Programmme schreiben die Settings nicht. Wer die Werte von Hand ändert - gut das kann passieren - aber der muss dann mit leben.
Die Settings werden zum ersten mal beim App Start geholt ( während der SplashScreen angezeigt wird)- danach nicht nochmal.
Der Dialog bleibt dann mit der Anwendung bestehen (kein löschen). Wenn die Anwendung crasht ist klar das dann nicht alles übernommen wurde.
thx so far!
Also es handlet sich <aktueller Ansatz> um die Standard Qt Elemente wie Combobox, lineEdit, Slider, etc pp.
Mein jetziger Ansatz sieht wie folgt aus:
- hinzufügen der Propertys für (Changed, KeyName, Type)
- beim verlassen die Liste der Objects holen
- aus der Liste wie franzf gesagt hat schauen ob es das property "value" [..] gibt
- dieses dann via einer lib in das Settings-File eintragen
Andere Programmme schreiben die Settings nicht. Wer die Werte von Hand ändert - gut das kann passieren - aber der muss dann mit leben.
Die Settings werden zum ersten mal beim App Start geholt ( während der SplashScreen angezeigt wird)- danach nicht nochmal.
Der Dialog bleibt dann mit der Anwendung bestehen (kein löschen). Wenn die Anwendung crasht ist klar das dann nicht alles übernommen wurde.
Naja, klingt als waeren die Anforderungen ned besonders kompliziert. Dann kannst dich auf ne ressourcenschonde (in bezug auf entwicklerressourcen ^^) Lösung konzentrieren.
Ob ich fuer jedes control so eigenschaften einpflegen wuerd ... hmmm
Ich hab mal MFC programmiert, daher hab ich sicher ne Affinitaet zu Austauschvariablen (DDX)
ich wuerd die controls mit den variablen kommunizieren lassen und mirn flag speichern, ob sich ueberhaupt was geaendert hat. Und wenn dann alles zurueckschreiben oder nix ^^
Fuer kleine und einmalige dialoge sicher ausreichend.
Mit deinem Ansatz koennte man hingegen wiederum ne Art framework bauen. Also wenn man die Properties vorgibt, die man braucht, einer von QDIalog abgeleiteten Framework-klasse nen QSettings Object gibt, und die Klasse sich dann komplett ums serialisieren von den aufgepeppten controls in nen QSetting kuemmert.
Würde sich sicher lohnen wenn man oft so kleine settingsdialogs bauen muss ....
Ciao ..
Ob ich fuer jedes control so eigenschaften einpflegen wuerd ... hmmm
Ich hab mal MFC programmiert, daher hab ich sicher ne Affinitaet zu Austauschvariablen (DDX)
ich wuerd die controls mit den variablen kommunizieren lassen und mirn flag speichern, ob sich ueberhaupt was geaendert hat. Und wenn dann alles zurueckschreiben oder nix ^^
Fuer kleine und einmalige dialoge sicher ausreichend.
Mit deinem Ansatz koennte man hingegen wiederum ne Art framework bauen. Also wenn man die Properties vorgibt, die man braucht, einer von QDIalog abgeleiteten Framework-klasse nen QSettings Object gibt, und die Klasse sich dann komplett ums serialisieren von den aufgepeppten controls in nen QSetting kuemmert.
Würde sich sicher lohnen wenn man oft so kleine settingsdialogs bauen muss ....
Ciao ..