読者です 読者をやめる 読者になる 読者になる

めいくりぷとのブログ

技術的なことやゲームのことやら・・・

QXmlStreamReader/Writerでxmlにウィジェットのステータスを保存する

サンプルコード

CConfigManager.hpp

#pragma once

#include <qwidget.h>
#include <map>

class CConfigManager
{
public:
	CConfigManager();
	~CConfigManager();

public:
	// 
	void WriteXmlElement(__in QXmlStreamWriter &writer);
	void ReadFromXml(__in QXmlStreamReader &reader);

	// for qwidget
	QCheckBox *CreateCheckBox(__in const QString &name, __in QWidget *parent = 0);
	QSpinBox *CreateSpinBox(__in const QString &name, __in QWidget *parent = 0);
	QLineEdit *CreateLineEdit(__in const QString &name, __in QWidget *parent = 0);
	QComboBox *CreateComboBox(__in const QString &name, __in QWidget *parent = 0);
	QPushButton *CreatePushButton(__in const QString &name, __in bool checkable, __in QWidget *parent = 0);
	QRadioButton *CreateRudioButton(__in const QString &name, __in QWidget *parent = 0);
	QSlider *CreateSlider(__in const QString &name, __in QWidget *parent = 0);

	static CConfigManager *GetInstance()
	{
		static CConfigManager instance;
		return &instance;
	}

private:
	void WriteXmlSettingsElement(__in QXmlStreamWriter &writer);
	void ReadXmlSettings(__in QXmlStreamReader &reader);

	void ReadXmlCheckBox(__in QXmlStreamReader &reader);
	void ReadXmlSpinBox(__in QXmlStreamReader &reader);
	void ReadXmlLineEdit(__in QXmlStreamReader &reader);
	void ReadXmlComboBox(__in QXmlStreamReader &reader);
	void ReadXmlPushButton(__in QXmlStreamReader &reader);
	void ReadXmlRadioButton(__in QXmlStreamReader &reader);
	void ReadXmlSlider(__in QXmlStreamReader &reader);

	// for qwidget
	std::map<QString, QCheckBox*> m_mCheckBox;
	std::map<QString, QSpinBox*> m_mSpinBox;
	std::map<QString, QLineEdit*> m_mLineEdit;
	std::map<QString, QComboBox*> m_mComboBox;
	std::map<QString, QPushButton*> m_mPushButton;
	std::map<QString, QRadioButton*> m_mRadioButton;
	std::map<QString, QSlider*> m_mSlider;
};

CConfigManager.cpp

#include "stdafx.h"

#include "CConfigManager.hpp"

CConfigManager::CConfigManager()
{
}

CConfigManager::~CConfigManager()
{
}

void CConfigManager::WriteXmlElement(__in QXmlStreamWriter &writer)
{
	// settings
	this->WriteXmlSettingsElement(writer);
}

void CConfigManager::WriteXmlSettingsElement(__in QXmlStreamWriter &writer)
{
	writer.writeStartElement("settings");

	foreach(auto it, this->m_mCheckBox)
	{
		if (it.second && it.first.size() > 1)
		{
			writer.writeStartElement("checkbox");
			writer.writeTextElement("name", it.first);
			writer.writeTextElement("state", QString::number(it.second->isChecked()));
			writer.writeEndElement();
		}
	}

	writer.writeEndElement();
}

void CConfigManager::ReadFromXml(__in QXmlStreamReader &reader)
{
	while (!reader.atEnd() && !reader.hasError())
	{
		QXmlStreamReader::TokenType token = reader.readNext();
		if (token == QXmlStreamReader::StartElement)
		{
			if (reader.name() == "settings")
			{
				// settings
				this->ReadXmlSettings(reader);
			}
		}
	}
}

void CConfigManager::ReadXmlSettings(__in QXmlStreamReader &reader)
{
	while (!reader.atEnd() && !reader.hasError())
	{
		QXmlStreamReader::TokenType token = reader.readNext();
		if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == "settings")
		{
			// element item end
			break;
		}
		if (token == QXmlStreamReader::StartElement)
		{
			if (reader.name() == "checkbox")
				this->ReadXmlCheckBox(reader);
		}
	}
}

void CConfigManager::ReadXmlCheckBox(__in QXmlStreamReader &reader)
{
	QString name = QString();
	while (!reader.atEnd() && !reader.hasError())
	{
		QXmlStreamReader::TokenType token = reader.readNext();
		if (reader.tokenType() == QXmlStreamReader::EndElement && reader.name() == "checkbox")
		{
			// element item end
			break;
		}
		if (token == QXmlStreamReader::StartElement)
		{
			if (reader.name() == "name")
				name = reader.readElementText();
			else if (reader.name() == "state" && name.length() > 1)
				this->m_mCheckBox[name]->setChecked(reader.readElementText().toInt());
		}
	}
}

// thanks to mahorori
QCheckBox *CConfigManager::CreateCheckBox(__in const QString &name, __in QWidget *parent)
{
	QCheckBox *checkBox = new QCheckBox(name, parent);
	this->m_mCheckBox[name] = checkBox;
	return checkBox;
}
//

...

使い方

CMainWindow::CMainWindow(__in QWidget *parent) : QMainWindow(parent)
{
        CConfigManager *pConfig = CConfigManager::GetInstance();
        QCheckBox *chkTestBox = pConfig->CreateCheckBox("Test Box");

        connect(chkTestBox, &QCheckBox::toggled, [=](bool toggled)
        {
                //
        }
        ...
}

void CMainWindow::OnLoad()
{
	QSettings settings;
	QString sFileName = QFileDialog::getOpenFileName(this, QString(), settings.value("filename").toString(), tr("Xml Files (*.xml)"));
	if (sFileName.isEmpty())
	{
		QMessageBox::warning(this, QString(), tr("Unknown error occurred."), QMessageBox::Ok);
		return;
	}

	QFile file(sFileName);
	if (!file.open(QIODevice::ReadOnly))
	{
		QMessageBox::warning(this, QString(), file.errorString(), QMessageBox::Ok);
		return;
	}

	CConfigManager::GetInstance()->ReadFromXml(QXmlStreamReader(&file));

	this->m_sXmlFileName = sFileName;
}

void CMainWindow::OnSave()
{
	if (this->m_sXmlFileName.isEmpty())
	{
		// no file exists, try to save as...
		this->OnSaveAs();
		return;
	}

	QFile file(this->m_sXmlFileName);
	if (!file.open(QIODevice::WriteOnly))
	{
		QMessageBox::warning(this, QString(), file.errorString(), QMessageBox::Ok);
		return;
	}

	QXmlStreamWriter writer(&file);
	writer.setAutoFormatting(true);
	writer.setAutoFormattingIndent(4);
	writer.writeStartDocument();

	// write elements
	writer.writeStartElement("XmlTester");
	CConfigManager::GetInstance()->WriteXmlElement(writer);
	writer.writeEndElement();

	file.close();

	QMessageBox::information(this, QString(), tr("Done."), QMessageBox::Ok);
}

void CMainWindow::OnSaveAs()
{
	//
	QString sFileName = QFileDialog::getSaveFileName(this, QString(), QString(), tr("Xml Files (*.xml)"));
	if (sFileName.isEmpty())
	{
		// QMessageBox::warning(this, QString(), tr("Unknown error occurred."), QMessageBox::Ok);
		return;
	}

	this->m_sXmlFileName = sFileName;
	this->OnSave();
}