QT 对话框等界面上输入值的保存,以自定义类序列化的方式

对于很多专业软件来说,每次计算都要在界面上需要输入很多参数。类似下图这样的:
QT 对话框等界面上输入值的保存,以自定义类序列化的方式_第1张图片
每次运行,这些参数大部分是相同的,需要保存下来以免每次都重新输入。

主要的输入控件是 QLineEdit,因为界面上输入区域 QLineEdit太多,不方便用JSON、XML或Setting的方式,按名称/数值 对一个个保存。
因此采用序列化的保存方式,但是qt不能对一般的QWidget序列化,更不用说以QWidget为成员的QList,编译时就会出错。
而且保存全部QWidget信息没有必要,我们关心的只是名称和数值,name and value

因此自定义了一个 WidgetInfo 类,并实现了它的序列化

class WidgetInfo
{
   public:
      QString name  ;
      QString value ;

      //重载运算符
      friend QDataStream & operator << ( QDataStream &dataStream, const WidgetInfo &wi  ){
          dataStream << wi.name << wi.value ;
          return dataStream ;
      }

      friend QDataStream & operator >> ( QDataStream &dataStream, WidgetInfo &wi ){
          dataStream >> wi.name >> wi.value ;
          return dataStream ;
      }
};

所有要保存的widget,必须用 setObjectName() 设置过名字,在创建widget时设置。
因为 w->objectName() 这个函数不能返回对象名或变量名, 它返回的只是setObjectName() 设置的名字 ,
用QDesigner创建的界面,已经执行了setObjectName,
手工创建的界面,必须用 setObjectName() 设置名字。

目前代码只处理了 QLineEdit的保存,其它控件类似。

上代码:

QtWidgetsSaveLoad.h

#ifndef QTWIDGETSSAVELOAD_H
#define QTWIDGETSSAVELOAD_H

#include 
#include 
#include 


class WidgetInfo
{
   public:
      QString name  ;
      QString value ;

      //重载运算符
      friend QDataStream & operator << ( QDataStream &dataStream, const WidgetInfo &wi  ){
          dataStream << wi.name << wi.value ;
          return dataStream ;
      }

      friend QDataStream & operator >> ( QDataStream &dataStream, WidgetInfo &wi ){
          dataStream >> wi.name >> wi.value ;
          return dataStream ;
      }
};

class QtWidgetsSaveLoad
{

public:
    QtWidgetsSaveLoad();

    void addWidget( QLineEdit *w ) ;

    void saveToFile( QWidget *parent ) ;
    void loadFromFile( QWidget *parent ) ;

    void setFilenameWithPath( const QString &filenameWithPath) ;

    QList <WidgetInfo> widgetInfoList ;

protected:

    QString filename ;
    QString workPath ;

    void gatherChildrenWidgetInfo( QWidget *parent ) ;
    void setChildrenWidgetValue( QWidget *parent ) ;

};

#endif // QTWIDGETSSAVELOAD_H

QtWidgetsSaveLoad.cpp

#include "QtWidgetsSaveLoad.h"

#include 

QtWidgetsSaveLoad::QtWidgetsSaveLoad()
{

}

void QtWidgetsSaveLoad::addWidget( QLineEdit *w )
{

    WidgetInfo wi ;

    wi.name  = w->objectName() ;
    wi.value = w->text() ;

    widgetInfoList.append( wi ) ;

}

void  QtWidgetsSaveLoad::gatherChildrenWidgetInfo( QWidget *parent )
{
    // 收集控件信息,保存到 QList  WidgetInfo
    QList <QLineEdit*> list = parent->findChildren<QLineEdit *>();
    for( int i = 0 ; i < list.size(); i++)
    {
        QLineEdit *le = list.at(i) ;
        if( le->objectName() == "" )
            qDebug() << "widget should run setObjectName() to set a name;" ;
        else {
            WidgetInfo wi ;
            wi.name  = le->objectName() ;
            wi.value = le->text() ;
            widgetInfoList.append( wi ) ;
        }
   }
}

void QtWidgetsSaveLoad::setChildrenWidgetValue( QWidget *parent )
{

    QList <QLineEdit*> list = parent->findChildren<QLineEdit *>();
    for( int i = 0 ; i < widgetInfoList.size() ;i++ ){
        for(int j = 0 ; j < list.size(); j++)
        {
            QLineEdit *le = list.at(j) ;
            if( le->objectName() == widgetInfoList.at(i).name )
            le->setText( widgetInfoList.at(i).value ) ;
       }
    }
}

// 所有要保存的widget,必须用 setObjectName() 设置过名字,在创建widget时设置
// 因为 w->objectName() 这个函数不能返回对象名或变量名,
// 它返回的只是 setObjectName() 设置的名字 , 用QDesigner创建的界面,已经设置了setObjectName

void  QtWidgetsSaveLoad::saveToFile( QWidget *parent )
{

    // 收集控件信息,保存到 QList  WidgetInfo 中
    gatherChildrenWidgetInfo( parent ) ;

    // 把  QList  WidgetInfo 序列化 到文件中
    QString allpath = workPath + "\\" + filename ;
    QFile file( allpath  ) ;

    if( file.open( QIODevice::ReadWrite  ) ){
        QDataStream stream( &file ) ;
        stream << widgetInfoList ;
        file.close();
    }
    else {
        qDebug() << allpath + " open error!" ;
    }
}

void  QtWidgetsSaveLoad::loadFromFile( QWidget *parent )
{
    // 通过 序列化 读取文件中信息到 QList  WidgetInfo
    QString allpath = workPath + "\\" + filename ;
    QFile file( allpath  ) ;

    if( file.open( QIODevice::ReadOnly  ) ){
        QDataStream stream( &file ) ;
        stream >> widgetInfoList ;
        file.close();
    }
    else {
        qDebug() << allpath + " open error!" ;
    }

    setChildrenWidgetValue( parent ) ;
}

void QtWidgetsSaveLoad::setFilenameWithPath( const QString &filenameWithPath)
{

    QFileInfo fileinfo = QFileInfo( filenameWithPath );

    filename = fileinfo.fileName();
    workPath = fileinfo.absolutePath();

}

你可能感兴趣的:(QT编程)