Seite 1 von 1

alle Formularwerte speichern und laden

Verfasst: 17. Juni 2007 02:31
von GoaSkin
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?

Verfasst: 17. Juni 2007 03:13
von Whitefurrows
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

Verfasst: 17. Juni 2007 08:38
von upsala
Und das hier:

Code: Alles auswählen

QMetaProperty QMetaObject::userProperty () const

Verfasst: 19. Juni 2007 00:26
von GoaSkin
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....

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();	
	}

Verfasst: 19. Juni 2007 09:05
von upsala
widgetEntry.append(allDoubleSpinBoxes[ii].objectName);
objectName ist eine Funktion und keine Variable...

Verfasst: 19. Juni 2007 12:46
von GoaSkin
Ich dachte objectName hat einen Rückgabewert vom Typ QString. Was müsste ich ändern, um den im Designer gesetzten Feldnamen zu erhalten?

Verfasst: 19. Juni 2007 13:52
von macman
Um einen Rückgabewert zu bekommen, musst Du aber auch die Funktion aufrufen.

Code: Alles auswählen

widgetEntry.append(allDoubleSpinBoxes[ii].objectName());

Re: alle Formularwerte speichern und laden

Verfasst: 18. Juni 2019 12:15
von GoaSkin
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?

Re: alle Formularwerte speichern und laden

Verfasst: 25. Juni 2019 22:05
von veeman
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:

Code: Alles auswählen

auto items = this->findChildren<QWidget*>();
std::sort(items.begin(), items.end(), [](QWidget *a, QWidget* b) { return a->objectName() < b->objectName(); });
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:

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();
}