第51课 - 程序中的配置文件和命令行参数

1、程序中的配置文件 

应用程序在运行后都有一个初始化的状态 

一般而言: 

       -程序的初始状态是最近一次运行退出前的状态 

问题 

          如何保存恢复程序状态? 

解决思路 

       -程序退出前保存状态参数到文件(数据库

       -程序再次启动时读出状态参数并恢复 

 

状态参数的存储方式 

       -文本文件格式(XML, Json, 等) 

       -轻量级数据库(Access, SQLite, 等) 

       -私有二进制文件格式 

 

Qt中的解决方案 

       -通过二进制数据流将状态参数直接存储于文件中 

       -优势: 

                   参数的存储和读取简单高效,易于编码实现 

                   最终文件为二进制格式,不易被恶意修改 

设计与实现 

    

 

2、主窗口的状态参数 

主窗口的状态参数 

       -应用程序必须保存和恢复主窗口的状态参数 

               ★ 位 置 ,大小

问题 

       -什么时候保存主窗口的状态数据? 

 

应用程序退出的过程 

           1. 收到关闭事件 

           2. 执行关闭事件处理函数 

           3. 主窗口从屏幕上消失 

           4. 主窗口的析构函数执行 

           5 . 。。。

一般而言 

       -应用程序收到关闭事件时进行状态参数的保存 

 

Qt中的解决方案 

          1. 重写关闭事件处理函数 

          2. 在关闭事件处理函数中保存状态参数 

3、编程实验 

文本编辑器的状态配置,主窗口的状态参数     NotePad.pro 

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): 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);    //在AppConfig构造函数中初始化成员变量

        config.store();    //保存到配置文件

        QMainWindow::closeEvent(e);
    }
    else
    {
        e->ignore();
    }
}

4、命令行参数的应用 

每一个应用程序都能够接收命令行参数 

问题 :

         GUI系统中命令行参数如何传递到应用程序? 

命令行参数的应用一 

       -传统应用方式 

                    在命令行启动GUI程序时传递参数 

        

命令行参数的应用二 

       -操作系统关联方式 

                    在文件被双击时,操作系统根据文件后缀选择应用程序 

                    将文件路径作为命令行参数启动应用程序 

         

5、编程实验 

处理命令行参数    NotePad.pro 

main.cpp

#include <QtGui/QApplication>
#include <QFileInfo>
#include "MainWindow.h"

int main(int argc, char *argv[]) //关于main()的参数相关知识,在C语言进阶剖析已介绍
{
    QApplication a(argc, argv);
    MainWindow* w = MainWindow::NewInstance();
    int ret = -1;

    if( w != NULL )
    {
        if( argc > 1 )
        {
            QFileInfo fi(argv[1]);

            if( fi.exists() )
            {
                w->openFile(fi.absoluteFilePath());
            }
        }

        w->show();

        ret = a.exec();
    }

    delete w;

    return ret;
}

6、小结 

应用程序中在退出时保存程序状态(用户配置) 

应用程序启动时恢复最近一次的程序状态 

可以通过二进制数据流将状态参数直接存储于文件中 

二进制数据流的方式非常的安全,简单,高效 

GUI程序主窗口的相关参数必须保存 

GUI程序在收到关闭事件时保存状态参数 

GUI程序依然能够接收命令行参数 

操作系统将文件的路径作为命令行参数传递 

 

猜你喜欢

转载自blog.csdn.net/qq_39654127/article/details/81698678