alle Formularwerte speichern und laden

Alles rund um die Programmierung mit Qt
Antworten
GoaSkin
Beiträge: 96
Registriert: 13. Juni 2007 00:14
Wohnort: Darmstadt

alle Formularwerte speichern und laden

Beitrag von GoaSkin » 17. Juni 2007 02:31

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?

Whitefurrows
Beiträge: 138
Registriert: 1. Mai 2006 19:50

Beitrag von Whitefurrows » 17. Juni 2007 03:13

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

upsala
Beiträge: 3946
Registriert: 5. Februar 2006 21:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala » 17. Juni 2007 08:38

Und das hier:

Code: Alles auswählen

QMetaProperty QMetaObject::userProperty () const

GoaSkin
Beiträge: 96
Registriert: 13. Juni 2007 00:14
Wohnort: Darmstadt

Beitrag von GoaSkin » 19. Juni 2007 00:26

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

upsala
Beiträge: 3946
Registriert: 5. Februar 2006 21:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala » 19. Juni 2007 09:05

widgetEntry.append(allDoubleSpinBoxes[ii].objectName);
objectName ist eine Funktion und keine Variable...

GoaSkin
Beiträge: 96
Registriert: 13. Juni 2007 00:14
Wohnort: Darmstadt

Beitrag von GoaSkin » 19. Juni 2007 12:46

Ich dachte objectName hat einen Rückgabewert vom Typ QString. Was müsste ich ändern, um den im Designer gesetzten Feldnamen zu erhalten?

macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman » 19. Juni 2007 13:52

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.

GoaSkin
Beiträge: 96
Registriert: 13. Juni 2007 00:14
Wohnort: Darmstadt

Re: alle Formularwerte speichern und laden

Beitrag von GoaSkin » 18. Juni 2019 12:15

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?

veeman
Beiträge: 265
Registriert: 3. Oktober 2012 01:43
Kontaktdaten:

Re: alle Formularwerte speichern und laden

Beitrag von veeman » 25. Juni 2019 22:05

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

mage-dev

Antworten