文章目录
1 文本编辑器中的配置文件
程序中的配置文件:
- 应用程序在运行后都有一个初始化的状态。
- 一般而言,程序的初始化状态是最近一次运行退出前的状态。
问题:如何保存和恢复程序状态呢?
解决思路:
- 程序退出前保存状态参数到文件(数据库)。
- 程序再次启动时读出状态参数并恢复。
状态参数的存储方式:
- 文本文件格式(XML、JSON等)。
- 轻量级数据库(Access、SQLite等)。
- 私有二进制文件格式。
Qt中的解决方案:
- 通过二进制数据流将状态参数直接存储于文件中。
- 优势:
- 参数的存储和读取简单高效,易于编码实现。
- 最终为二进制格式,不易被恶意修改。
设计与实现:
问题:什么时候保存主窗口的状态数据?
应用程序退出的过程:
- 收到关闭事件。
- 执行关闭事件处理函数。
- 主窗口从屏幕上消失。
- 主窗口的析构函数执行。
- …
一般而言:
- 应用程序收到关闭事件时进行状态参数的保存。
Qt中的解决方案:
- 重写关闭事件处理函数。
- 在关闭事件处理函数中保存状态参数。
AppConfig.h:
#ifndef _APPCONFIG_H_
#define _APPCONFIG_H_
#include <QObject>
#include <QFont>
#include <QSize>
#include <QPoint>
class AppConfig : public QObject
{
Q_OBJECT
QFont m_editorFont;
QSize m_mainWindowSize;
QPoint m_mainWindowPoint;
bool m_isAutoWrap;
bool m_isToolBarVisible;
bool m_isStatusBarVisible;
bool m_isValid;
bool restore();
public:
explicit AppConfig(QObject* parent = 0);
explicit AppConfig(QFont font, QPoint point, QSize size, bool isWrap, bool tbVisible, bool sbVisible, QObject* parent = 0);
bool store();
QFont editorFont();
QSize mainWindowSize();
QPoint mainWindowPoint();
bool isAutoWrap();
bool isToolBarVisible();
bool isStatusBarVisible();
bool isValid();
};
#endif // _APPCONFIG_H_
AppConfig.cpp:
#include "AppConfig.h"
#include <QFile>
#include <QDataStream>
#include <QApplication>
AppConfig::AppConfig(QObject* parent) : QObject(parent)
{
m_isValid = restore();
}
AppConfig::AppConfig(QFont font, QPoint point, QSize size, bool isWrap, bool tbVisible, bool sbVisible, QObject* parent)
{
m_editorFont = font;
m_mainWindowPoint = point;
m_mainWindowSize = size;
m_isAutoWrap = isWrap;
m_isToolBarVisible = tbVisible;
m_isStatusBarVisible = sbVisible;
m_isValid = true;
}
bool AppConfig::restore()
{
bool ret = true;
QFile file(QApplication::applicationDirPath() + "/app.config");
if( file.open(QIODevice::ReadOnly) )
{
QDataStream in(&file);
in.setVersion(QDataStream::Qt_4_7);
in >> m_editorFont;
in >> m_mainWindowPoint;
in >> m_mainWindowSize;
in >> m_isAutoWrap;
in >> m_isToolBarVisible;
in >> m_isStatusBarVisible;
file.close();
}
else
{
ret = false;
}
return ret;
}
bool AppConfig::store()
{
bool ret = true;
QFile file(QApplication::applicationDirPath() + "/app.config");
if( file.open(QIODevice::WriteOnly) )
{
QDataStream out(&file);
out.setVersion(QDataStream::Qt_4_7);
out << m_editorFont;
out << m_mainWindowPoint;
out << m_mainWindowSize;
out << m_isAutoWrap;
out << m_isToolBarVisible;
out << m_isStatusBarVisible;
file.close();
}
else
{
ret = false;
}
return ret;
}
QFont AppConfig::editorFont()
{
return m_editorFont;
}
QSize AppConfig::mainWindowSize()
{
return m_mainWindowSize;
}
QPoint AppConfig::mainWindowPoint()
{
return m_mainWindowPoint;
}
bool AppConfig::isAutoWrap()
{
return m_isAutoWrap;
}
bool AppConfig::isToolBarVisible()
{
return m_isToolBarVisible;
}
bool AppConfig::isStatusBarVisible()
{
return m_isStatusBarVisible;
}
bool AppConfig::isValid()
{
return m_isValid;
}
界面初始化时读取数据:
bool MainWindow::construct()
{
bool ret = true;
AppConfig config;
ret = ret && initMenuBar();
ret = ret && initToolBar();
ret = ret && initStatusBar();
ret = ret && initMainEditor();
if( config.isValid() )
{
mainEditor.setFont(config.editorFont());
if( !config.isAutoWrap() )
{
mainEditor.setLineWrapMode(QPlainTextEdit::NoWrap);
findMenuBarAction("Auto Wrap")->setChecked(false);
findToolBarAction("Auto Wrap")->setChecked(false);
}
if( !config.isToolBarVisible() )
{
toolBar()->setVisible(false);
findMenuBarAction("Tool Bar")->setChecked(false);
findToolBarAction("Tool Bar")->setChecked(false);
}
if( !config.isStatusBarVisible() )
{
statusBar()->setVisible(false);
findMenuBarAction("Status Bar")->setChecked(false);
findToolBarAction("Status Bar")->setChecked(false);
}
move(config.mainWindowPoint());
resize(config.mainWindowSize());
}
return ret;
}
关闭程序时保存数据:
void MainWindow::closeEvent(QCloseEvent* e)
{
preEditorChange();
if( !m_isTextChanged )
{
QFont font = mainEditor.font();
bool isWrap = (mainEditor.lineWrapMode() == QPlainTextEdit::WidgetWidth);
bool tbVisible = toolBar()->isVisible();
bool sbVisible = statusBar()->isVisible();
AppConfig config(font, pos(), size(), isWrap, tbVisible, sbVisible);
config.store();
QMainWindow::closeEvent(e);
}
else
{
e->ignore();
}
}
参考资料: