alle Formularwerte speichern und laden
alle Formularwerte speichern und laden
Für ein Programm benötige ich eine Funktion, die die Inhalte von Formularfeldern (hauptsächlich Textfelder, Slider und Spinboxen) in irgend einer Form in eine Datei speichert.
Da es aber eine mühsame Arbeit wäre, Variable für Variable durchzugehen und in eine Datei abzulegen (bei ca. 200 Eingabe-Widgets) würde es mich einmal interessieren, ob QT vielleicht eine Funktion bietet, die alle Werte eines Fensters als XML-Datei exportiert und anhand einer solchen Datei auch die Werte wieder neu setzen. Naja, fündig wurde ich in der Referenz nicht. Wenn QT das nicht kann, weiss jemand ggf. ob es wo eine solche Funktion zum Download gibt?
Da es aber eine mühsame Arbeit wäre, Variable für Variable durchzugehen und in eine Datei abzulegen (bei ca. 200 Eingabe-Widgets) würde es mich einmal interessieren, ob QT vielleicht eine Funktion bietet, die alle Werte eines Fensters als XML-Datei exportiert und anhand einer solchen Datei auch die Werte wieder neu setzen. Naja, fündig wurde ich in der Referenz nicht. Wenn QT das nicht kann, weiss jemand ggf. ob es wo eine solche Funktion zum Download gibt?
-
- Beiträge: 138
- Registriert: 1. Mai 2006 19:50
Hallo,
schaue dir mal folgende funktionen von QWidget an:
http://doc.trolltech.com/4.2/qobject.html#findChildren
http://doc.trolltech.com/4.2/qobject.ht ... Children-2
so solltest du alle Werte recht einfach auslesen können, wie du sie dann abspeicherst bleibt dir überlassen.
Gruß,
Whitefurrows
schaue dir mal folgende funktionen von QWidget an:
http://doc.trolltech.com/4.2/qobject.html#findChildren
http://doc.trolltech.com/4.2/qobject.ht ... Children-2
so solltest du alle Werte recht einfach auslesen können, wie du sie dann abspeicherst bleibt dir überlassen.
Gruß,
Whitefurrows
Und das hier:
Code: Alles auswählen
QMetaProperty QMetaObject::userProperty () const
danke für die Tipps erstmal...
ich versuche gerade, eine Funktion zum Speichern zu erzeugen, wobei er hier im Array die Objekt-Eigenschaften (hier: objectName und textFromValue) nicht mehr erkennt....
ich versuche gerade, eine Funktion zum Speichern zu erzeugen, wobei er hier im Array die Objekt-Eigenschaften (hier: objectName und textFromValue) nicht mehr erkennt....
Code: Alles auswählen
// save XML file of all the needed form values into the user directory
bool SC4C::save()
{
// find out what necessary values do exist... if you want to use new widgets in the UI, you need to modify this function
QList<QDoubleSpinBox *> allDoubleSpinBoxes = qFindChildren<QDoubleSpinBox *>(this);
QList<QSpinBox *> allSpinBoxes = qFindChildren<QSpinBox *>(this);
QList<QSlider *> allSliders = qFindChildren<QSlider *>(this);
// create template XML file (actually static, may be dynamized in future versions)
QFile file;
file.setFileName("sc4config.conf");
file.open(stderr, QIODevice::WriteOnly);
file.write("<XML>\n");
file.write("<DoubleSpinBoxes>\n");
// create arrays with widget contents
for(int ii = 0; ii < allDoubleSpinBoxes.size(); ++ii)
{
QString widgetEntry = "<Element NAME=\"";
widgetEntry.append(allDoubleSpinBoxes[ii].objectName);
widgetEntry.append("\" VALUE=\"");
widgetEntry.append(allDoubleSpinBoxes[ii].textFromValue);
widgetEntry.append("\"/>\n");
file.write(widgetEntry, qstrlen(widgetEntry));
}
// close and save the configuration file
file.write("</DoubleSpinBoxes>\n");
file.write("</XML>\n");
file.close();
}
Um einen Rückgabewert zu bekommen, musst Du aber auch die Funktion aufrufen.
Code: Alles auswählen
widgetEntry.append(allDoubleSpinBoxes[ii].objectName());
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
Re: alle Formularwerte speichern und laden
Hallo,
12 Jahre später bin ich wieder im Rahmen eines anderen Projektes bei diesem Thema und krame deshalb den alten Topic wieder raus.
Gibt es eine Möglichkeit, mit qFindchildren auch eine Liste zu erzeugen, die alphabetisch nach dem Widget-Namen statt nach der Definitionsreihenfolge sortiert ist?
12 Jahre später bin ich wieder im Rahmen eines anderen Projektes bei diesem Thema und krame deshalb den alten Topic wieder raus.
Gibt es eine Möglichkeit, mit qFindchildren auch eine Liste zu erzeugen, die alphabetisch nach dem Widget-Namen statt nach der Definitionsreihenfolge sortiert ist?
Re: alle Formularwerte speichern und laden
qFindChildren ist obsolete, verwende direkt die findChildren funktion von QWidget bzw. QObject.
Und ja du kannst die zurückgegebene List nach belieben sortieren.
Beispiel um die Sortierung nach dem Namen durchzuführen:
Ansonsten kannst du diverse Widget Eigenschaften mit der Funktion property abfragen; anbei ein vollständiges Beispiel um diverse Widget Eigenschaften als Binary zu speichern / zu laden:
Und ja du kannst die zurückgegebene List nach belieben sortieren.
Beispiel um die Sortierung nach dem Namen durchzuführen:
Code: Alles auswählen
auto items = this->findChildren<QWidget*>();
std::sort(items.begin(), items.end(), [](QWidget *a, QWidget* b) { return a->objectName() < b->objectName(); });
Code: Alles auswählen
#include "QtGuiApplication.h"
#include <QCloseEvent>
#include <QWidget>
typedef void(*visualStateSelector)(QWidget * const widget, QSet<QString> &propertyList);
void defaultVisualStateSelector(QWidget * const widget, QSet<QString> &propertyList)
{
auto const lineEdit = qobject_cast<QLineEdit*>(widget);
if (lineEdit != nullptr)
{
propertyList << "text";
return;
}
auto const checkBox = qobject_cast<QCheckBox*>(widget);
if (checkBox != nullptr)
{
propertyList << "checked" << "tristate";
return;
}
auto const spinBox = qobject_cast<QSpinBox*>(widget);
if (spinBox != nullptr)
{
propertyList << "minimum" << "maximum" << "value";
return;
}
auto const doubleSpinBox = qobject_cast<QDoubleSpinBox*>(widget);
if (doubleSpinBox != nullptr)
{
propertyList << "minimum" << "maximum" << "value";
return;
}
auto const slider = qobject_cast<QAbstractSlider *>(widget);
if (slider != nullptr)
{
propertyList << "minimum" << "maximum" << "value";
return;
}
auto const abstractButton = qobject_cast<QAbstractButton*>(widget);
if (abstractButton != nullptr)
{
propertyList << "checked" << "down";
return;
}
}
void saveVisualState(QString const & fileName, QWidget const & widget, visualStateSelector const selector = defaultVisualStateSelector)
{
QFile file(fileName);
QVariantMap propertyMap;
for (auto const child: widget.findChildren<QWidget*>())
{
auto const name = child->objectName();
if (name.isEmpty())
continue;
auto const properties = child->property("store").toString();
auto propertyList = properties.split(",", QString::SkipEmptyParts).toSet();
selector(child, propertyList);
for (auto const property : propertyList)
{
auto const pname = property.trimmed();
auto const cname = pname.toStdString();
auto const value = child->property(cname.c_str());
propertyMap.insert(QString("%0.%1").arg(name).arg(pname), value);
}
}
if (file.open(QFile::WriteOnly | QFile::Truncate))
{
QDataStream out(&file);
out << propertyMap;
}
file.close();
}
void loadVisualState(QString const & fileName, QWidget & widget, visualStateSelector const selector = defaultVisualStateSelector)
{
QFile file(fileName);
if (!file.exists())
return;
QVariantMap propertyMap;
if (file.open(QFile::ReadOnly))
{
QDataStream out(&file);
out >> propertyMap;
}
else
return;
file.close();
for (auto const child : widget.findChildren<QWidget*>())
{
auto const name = child->objectName();
if (name.isEmpty())
continue;
auto const properties = child->property("store").toString();
auto propertyList = properties.split(",", QString::SkipEmptyParts).toSet();
selector(child, propertyList);
for (auto const property : propertyList)
{
auto const pname = property.trimmed();
auto const cname = pname.toStdString();
auto const key = QString("%0.%1").arg(name).arg(pname);
auto valueIt = propertyMap.constFind(key);
if (valueIt == propertyMap.constEnd())
continue;
child->setProperty(cname.c_str(), *valueIt);
}
}
}
QtGuiApplication::QtGuiApplication(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
loadVisualState("app.vstate", *this);
}
void QtGuiApplication::closeEvent(QCloseEvent *event)
{
saveVisualState("app.vstate", *this);
event->accept();
}