qsettings 中文键值 注释 支持

#ifndef SETTINGS_H

#define SETTINGS_H

#include <QString> 
#include <QVariant>

class QSettings;

class Settings 

public: 
    Settings(const QString & fileName); 
    ~Settings(); 
    void setValue ( const QString & key, const QVariant & value ); 
    QVariant value ( const QString & key, const QVariant & defaultValue = QVariant() ) const; 
private: 
    QSettings *d; 
};

#endif // SETTINGS_H

#include "settings.h" 
#include <QtGui>

QMap<int, QString> comments;

//#define LZM_DEBUG

bool readIniComment(QString fileName) 

    QFile file(fileName); 
    if (!file.open(QIODevice::ReadOnly)) 
    { 
        qDebug()<<"readIniComment open"<<fileName<<"failed!: error"<<file.error(); 
        return false; 
    }

QTextStream inStream(&file); 
    inStream.setCodec("UTF-8");

QString data; 
    bool ok = true;

int line=-1; 
    while (!inStream.atEnd()) 
    { 
        data = inStream.readLine(); 
        line++; 
        QString trimmed = data.trimmed(); 
        if(trimmed.isEmpty()) 
        { 
            continue; 
        } 
        else if(trimmed[0]== QChar(‘#‘) || trimmed[0]== QChar(‘;‘)) 
        { 
            comments[line] = data; 
#ifdef LZM_DEBUG 
            qDebug()<<"line"<<line<<"text"<<data; 
#endif


        else 
        { 
            continue; 
        } 
    }

return ok; 
}

bool WriteIniComment(QString fileName) 

    QFile inFile(fileName); 
    if (!inFile.open(QIODevice::ReadOnly)) 
    { 
        qDebug()<<"WriteIniComment open"<<fileName<<"failed!"; 
        return false; 
    }

QString outFileName = fileName+".out"; 
    QFile outfile(outFileName); 
    if (!outfile.open(QIODevice::WriteOnly)) 
    { 
        qDebug()<<"open"<<outFileName<<"failed!"; 
        return false; 
    }

QTextStream inStream(&inFile); 
    inStream.setCodec("UTF-8");

QTextStream outStream(&outfile); 
    outStream.setCodec("UTF-8");

QString data; 
    bool ok = true;

int line=-1;

while (!inStream.atEnd()) 
    { 
        data = inStream.readLine(); 
        line++; 
        QString trimmed = data.trimmed(); 
        //add comments 
        while(comments.contains(line)) 
        { 
            outStream <<comments[line]<<"\n"; 
#ifdef LZM_DEBUG 
            qDebug()<<"line"<<line<<"text"<<comments[line]; 
#endif 
            line++; 
        }

if(trimmed.isEmpty()) 
        { 
            outStream <<data<<"\n"; 
            continue; 
        } 
        else 
        { 
            outStream <<data<<"\n"; 
        } 
    }

inFile.close(); 
    outfile.close(); 
//

QFile::remove(fileName); 
    qDebug()<<"remove"<<fileName; 
    QFile::rename(outFileName, fileName); 
    qDebug()<<"rename"<<outFileName<<"to"<<fileName;

return ok; 
}

QStringList splitArgs(const QString &s, int idx) 

    int l = s.length(); 
    Q_ASSERT(l > 0); 
    Q_ASSERT(s.at(idx) == QLatin1Char(‘(‘)); 
    Q_ASSERT(s.at(l - 1) == QLatin1Char(‘)‘));

QStringList result; 
    QString item;

for (++idx; idx < l; ++idx) { 
        QChar c = s.at(idx); 
        if (c == QLatin1Char(‘)‘)) { 
            Q_ASSERT(idx == l - 1); 
            result.append(item); 
        } else if (c == QLatin1Char(‘ ‘)) { 
            result.append(item); 
            item.clear(); 
        } else { 
            item.append(c); 
        } 
    }

return result; 
}

QVariant stringToVariant(const QString &s) 

    if (s.startsWith(QLatin1Char(‘@‘))) { 
        if (s.endsWith(QLatin1Char(‘)‘))) { 
            if (s.startsWith(QLatin1String("@ByteArray("))) { 
                return QVariant(s.toLatin1().mid(11, s.size() - 12)); 
            } else if (s.startsWith(QLatin1String("@Variant("))) { 
#ifndef QT_NO_DATASTREAM 
                QByteArray a(s.toLatin1().mid(9)); 
                QDataStream stream(&a, QIODevice::ReadOnly); 
                stream.setVersion(QDataStream::Qt_4_0); 
                QVariant result; 
                stream >> result; 
                return result; 
#else 
                Q_ASSERT(!"QSettings: Cannot load custom types without QDataStream support"); 
#endif 
#ifndef QT_NO_GEOM_VARIANT 
            } else if (s.startsWith(QLatin1String("@Rect("))) { 
                QStringList args = ::splitArgs(s, 5); 
                if (args.size() == 4) 
                    return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt())); 
            } else if (s.startsWith(QLatin1String("@Size("))) { 
                QStringList args = ::splitArgs(s, 5); 
                if (args.size() == 2) 
                    return QVariant(QSize(args[0].toInt(), args[1].toInt())); 
            } else if (s.startsWith(QLatin1String("@Point("))) { 
                QStringList args = ::splitArgs(s, 6); 
                if (args.size() == 2) 
                    return QVariant(QPoint(args[0].toInt(), args[1].toInt())); 
#endif 
            } else if (s == QLatin1String("@Invalid()")) { 
                return QVariant(); 
            }


        if (s.startsWith(QLatin1String("@@"))) 
            return QVariant(s.mid(1)); 
    }

return QVariant(s); 
}

bool myReadFunc(QIODevice &device, QSettings::SettingsMap &settingsMap) 

        QString currentSection; 
        QTextStream stream(&device); 
        stream.setCodec("UTF-8"); 
        QString data; 
        bool ok = true; 
        while (!stream.atEnd()) 
        {

data = stream.readLine(); 
            if (data.trimmed().isEmpty()) 
            { 
                continue; 
            } 
            if (data[0] == QChar(‘[‘)) 
            { 
                QString iniSection; 
                int inx = data.indexOf(QChar(‘]‘)); 
                if (inx == -1){ 
                    ok = false; 
                    iniSection = data.mid(1); 
                } 
                else 
                { 
                    iniSection = data.mid(1, inx - 1); 
                } 
                iniSection = iniSection.trimmed(); 
                if (iniSection.compare(QString("general"), Qt::CaseInsensitive) == 0) 
                { 
                    currentSection.clear(); 
                } 
                else 
                { 
                    if (iniSection.compare(QString("%general"), Qt::CaseInsensitive) == 0) 
                    { 
                        currentSection = QString("general"); 
                    } 
                    else 
                    { 
                        currentSection = iniSection; 
                    } 
                    currentSection += QChar(‘/‘);


            } 
            else 
            { 
                bool inQuotes = false; 
                int equalsPos = -1; 
                QList<int> commaPos; 
                int i = 0; 
                while (i < data.size()) 
                { 
                    QChar ch = data.at(i); 
                    if (ch == QChar(‘=‘)) 
                    { 
                        if (!inQuotes && equalsPos == -1) 
                        { 
                            equalsPos = i; 
                        } 
                    } 
                    else if (ch == QChar(‘"‘)) 
                    { 
                        inQuotes = !inQuotes; 
                    } 
                    else if (ch == QChar(‘,‘)) 
                    { 
                        if (!inQuotes && equalsPos != -1) 
                        { 
                            commaPos.append(i); 
                        } 
                    } 
                    else if (ch == QChar(‘;‘) || ch == QChar(‘#‘)) 
                    { 
                        if (!inQuotes) 
                        { 
                            data.resize(i); 
                            break; 
                        } 
                    } 
                    else if (ch == QChar(‘\\‘)) 
                    { 
                        if (++i < data.size()) 
                        { 
                        } 
                        else 
                        { 
                            ok = false; 
                            break; 
                        } 
                    } 
                    i++; 
                } 
                if (equalsPos == -1) 
                { 
                    break; 
                } 
                else 
                { 
                    QString key = data.mid(0, equalsPos).trimmed(); 
                    if (key.isEmpty()) 
                    { 
                        break; 
                    } 
                    else 
                    { 
                        key = currentSection + key; 
                    } 
                    if (commaPos.isEmpty()) 
                    { 
                        //value 
                        QString v = data.mid(equalsPos+1).trimmed(); 
                        if (v.startsWith("\"") && v.endsWith("\"") && v.length()>1) 
                        { 
                            v = v.mid(1, v.length()-2); 
                        } 
                        settingsMap[key] = stringToVariant(v); 
                    } 
                    else 
                    { //value list 
                        commaPos.prepend(equalsPos); 
                        commaPos.append(-1); 
                        QVariantList vals; 
                        for (int i=1; i<commaPos.size(); ++i) 
                        { 
                            QString d = data.mid(commaPos.at(i-1)+1, commaPos.at(i)-commaPos.at(i-1)-1); 
                            QString v = d.trimmed(); 
                            if (v.startsWith("\"") && v.endsWith("\"") && v.length()>1) 
                            { 
                                v = v.mid(1, v.length()-2); 
                            } 
                            vals.append(stringToVariant(v) /*stringToVariant(unescapedString(v))*/); 
                        } 
                        settingsMap[key] = vals; 
                    } 
                } 
            } 
        }

return ok; 
}

QString variantToString(const QVariant &v) 

     QString result;

switch (v.type()) { 
         case QVariant::Invalid: 
             result = QLatin1String("@Invalid()"); 
             break;

case QVariant::ByteArray: { 
             QByteArray a = v.toByteArray(); 
             result = QLatin1String("@ByteArray("); 
             result += QString::fromLatin1(a.constData(), a.size()); 
             result += QLatin1Char(‘)‘); 
             break; 
         }

case QVariant::String: 
         case QVariant::LongLong: 
         case QVariant::ULongLong: 
         case QVariant::Int: 
         case QVariant::UInt: 
         case QVariant::Bool: 
         case QVariant::Double: 
         case QVariant::KeySequence: { 
             result = v.toString(); 
             if (result.startsWith(QLatin1Char(‘@‘))) 
                 result.prepend(QLatin1Char(‘@‘)); 
             break; 
         } 
#ifndef QT_NO_GEOM_VARIANT 
         case QVariant::Rect: { 
             QRect r = qvariant_cast<QRect>(v); 
             result += QLatin1String("@Rect("); 
             result += QString::number(r.x()); 
             result += QLatin1Char(‘ ‘); 
             result += QString::number(r.y()); 
             result += QLatin1Char(‘ ‘); 
             result += QString::number(r.width()); 
             result += QLatin1Char(‘ ‘); 
             result += QString::number(r.height()); 
             result += QLatin1Char(‘)‘); 
             break; 
         } 
         case QVariant::Size: { 
             QSize s = qvariant_cast<QSize>(v); 
             result += QLatin1String("@Size("); 
             result += QString::number(s.width()); 
             result += QLatin1Char(‘ ‘); 
             result += QString::number(s.height()); 
             result += QLatin1Char(‘)‘); 
             break; 
         } 
         case QVariant::Point: { 
             QPoint p = qvariant_cast<QPoint>(v); 
             result += QLatin1String("@Point("); 
             result += QString::number(p.x()); 
             result += QLatin1Char(‘ ‘); 
             result += QString::number(p.y()); 
             result += QLatin1Char(‘)‘); 
             break; 
         } 
#endif // !QT_NO_GEOM_VARIANT

default: { 
#ifndef QT_NO_DATASTREAM 
             QByteArray a; 
             { 
                 QDataStream s(&a, QIODevice::WriteOnly); 
                 s.setVersion(QDataStream::Qt_4_0); 
                 s << v; 
             }

result = QLatin1String("@Variant("); 
             result += QString::fromLatin1(a.constData(), a.size()); 
             result += QLatin1Char(‘)‘); 
#else 
             Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support"); 
#endif 
             break; 
         } 
     }

return result; 
}

bool myWriteFunc(QIODevice &device, const QSettings::SettingsMap &settingsMap) 

#ifdef Q_OS_WIN 
    const char * const eol = "\r\n"; 
#else 
    const char *eol = "\n"; 
#endif 
    bool writeError = false; 
    QString lastSection; 
    QMapIterator<QString,QVariant> it(settingsMap); 
    while(it.hasNext() && !writeError) 
    { 
        it.next(); 
        QString key = it.key(); 
        QString section; 
        qDebug()<<"key: "<<key; 
        int idx = key.lastIndexOf(QChar(‘/‘)); 
        if (idx == -1) 
        { 
            section = QString("[General]"); 
        } 
        else 
        { 
            section = key.left(idx); 
            key = key.mid(idx+1); 
            if (section.compare(QString("General"), Qt::CaseInsensitive) == 0) 
            { 
                section = QString("[%General]"); 
            } 
            else 
            { 
                section.prepend(QChar(‘[‘)); 
                section.append(QChar(‘]‘)); 
            } 
        } 
        if (section.compare(lastSection, Qt::CaseInsensitive)) 
        { 
            if (!lastSection.isEmpty()) 
            { 
                device.write(eol); 
            } 
            lastSection = section; 
            if (device.write(section.toUtf8() + eol) == -1) 
            { 
                writeError = true; 
            } 
        } 
        QByteArray block = key.toUtf8(); 
        block += " = "; 
        if (it.value().type() == QVariant::StringList) 
        { 
//            foreach (QString s, it.value().toStringList()) 
//            { 
//                block += /*escapedString(s)*/ s; 
//                block += ", "; 
//            } 
//            if (block.endsWith(", ")) 
//            { 
//                block.chop(2); 
//            } 
            qDebug()<< "no support QVariant::StringList"; 
        } 
        else if (it.value().type() == QVariant::List) 
        { 
//            foreach (QVariant v, it.value().toList()) 
//            { 
//                block += /*escapedString(variantToString(v))*/ v.toString(); 
//                block += ", "; 
//            } 
//            if (block.endsWith(", ")) 
//            { 
//                block.chop(2); 
//            } 
            qDebug()<< "no support QVariant::List"; 
        } 
        else 
        { 
//            block += /*escapedString*/(variantToString(it.value())); 
//            block += it.value().toString(); 
            block += variantToString(it.value()); 
        } 
        block += eol; 
        if (device.write(block) == -1) 
        { 
            writeError = true; 
        } 
    } 
    return writeError;

}

Settings::Settings(const QString & fileName) 

    readIniComment(fileName); 
    const QSettings::Format MyIniFormat = QSettings::registerFormat("ini", myReadFunc, myWriteFunc); 
    d= new QSettings(fileName, MyIniFormat); 
    d->setIniCodec("UTF-8"); 
}

Settings::~Settings() 

    if(d) 
    { 
        QString fileName = d->fileName();

delete d; 
        WriteIniComment(fileName); 
    }

}

void Settings::setValue(const QString &key, const QVariant &value) 

    d->setValue(key, value); 
}

QVariant Settings::value(const QString &key, const QVariant &defaultValue) const 

    return d->value(key, defaultValue); 
}

时间: 2024-11-09 09:30:51

qsettings 中文键值 注释 支持的相关文章

KVC - 键值编码

[基本概念] 1.键值编码是一个用于间接访问对象属性的机制,使用该机制不需要调用存取方法和变量实例就可访问对象属性. 2.键值编码方法在OC非正式协议(类目)NSKeyValueCoding中被声明,默认的实现方法由NSObject提供. 3.键值编码支持带有对象值的属性,同时也支持纯数值类型和结构.非对象参数和返回类型会被识别并自动封装/解封. [键值访问] 键值编码中的基本调用包括-valueForKey: 和 -setValue:forkey: 这两个方法,它们以字符串的形式向对象发送消息

键-值编码扩展

键-值编码扩展 CoreAnimation 扩展了 NSKeyValueCoding 协议,因为它从属 CAAnimation 和 CALayer 类.此扩展为某些键添加默认值,扩展封装约定,为 CGPoint.CGRect.CGSize.CATransform3D添加键路径支持 键-值编码遵从容器类 CAAnimation 和 CALayer 类是遵从容器类键-值编码,也就是说可以为任意键设置值.即使键没有在 CALayer类中声明的属性,你也可以用以下的方式设置值 [theLayer set

python字典中键值对的值为中文,打印成转义字符,怎么解决

今天是2019-10-02,学习代码第二天. python字典中键值对中有中文,打印的时候,发现成转义字符了.查了好久,解决.记录一下.useful. 今日份代码: 1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 # 字典和列表的区别 4 # 列表是有序的对象集合,字典是无序的对象集合 5 # 字典的特点,字典用{}定义,使用键值对存储数据,键值对间用,分开 6 # 键--key,索引 值--value,数据 键和值间用:分开 键--唯一的,只能取字

用字典给Model赋值并支持map键值替换

这个是昨天教程的升级版本,支持键值的map替换. 源码如下: NSObject+Properties.h 与 NSObject+Properties.m // // NSObject+Properties.h // // Created by YouXianMing on 14-9-4. // Copyright (c) 2014年 YouXianMing. All rights reserved. // #import <Foundation/Foundation.h> @interface

将任意一个jQuery对象进行表单序列化,免除了提交请求时大量拼写表单数据的烦恼,支持键值对&lt;name&amp;value&gt;格式和JSON格式。

http://zhengxinlong.iteye.com/blog/848712 将任意一个jQuery对象进行表单序列化,免除了提交请求时大量拼写表单数据的烦恼,支持键值对<name&value>格式和JSON格式. /// <reference name="jquery.js" description="1.3.2版本以上" /> /*!* 扩展jQuery表单序列化函数:{ Version: 1.2, Author: Eric

(转)QT中文乱码与国际化支持

Qt内部采用的全Unicode编码,这从根本上保证了多国语界面实现的正确性和便捷性.Qt本身提供的linguist工具,用来实现翻译过程十分方便.MFC中利用资源DLL切换资源,或使用多个RC文件进行不同语言版本编译等方法都十分麻烦,如果你曾经使用过MFC,QT解决多语言问题的便捷性绝对会让你感觉是一种享受.本文讨论以下几个方面内容: 1.  QT中解决中文乱码的方法: 2.  QT中实现国家化支持. 3.  对话框实现多语言 一.       中文乱码 1.  在程序中直接使用中文,需要在程序

appium键值对的应用

平时大家应用键值对的时候或许很难找,下面的几行代码能让大家方便一点,只要把需要修改的改成自己需要的就OK了! cap.setCapability("automationName", "Appium");                     //appium做自动化        cap.setCapability("deviceName", "设备名");                                 /

mybatis中useGeneratedKeys用法--插入数据库后获取主键值

前言:今天无意在mapper文件中看到useGeneratedKeys这个词,好奇就查了下,发现能解决我之前插入有外键表数据时,这个外键获取繁琐的问题,于是学习敲DEMO记录    在项目中经常需要获取到插入数据的主键来保障后续操作,数据库中主键一般我们使用自增或者uuid()的方式自动生成 问题:对于uuid使用Java代码生成的方式还比较容易控制,然而使用数据库生成的主键,这样我们就需要将插入的数据再查询出来得到主键,某些情况下还可能查询到多条情况,这样就比较尴尬了. 那有什么办法来插入数据

20150218【改进信号量】IMX257实现GPIO-IRQ中断按键获取键值驱动程序

[改进信号量]IMX257实现GPIO-IRQ中断按键获取键值驱动程序 2015-02-18 李海沿 前面我们使用POLL查询方式来实现GPIO-IRQ按键中断程序 这里我们来使用信号量,让我们的驱动同时只能有一个应用程序打开. 一.首先在前面代码的基础上来一个简单的信号 1.定义一个全局的整形变量 2.在打开函数中,每次进入打开函数canopen都自减1, 3.当我们不使用时,在realease 中canopen自加1 4.这样就实现了一个简单的信号量,我们编译,测试 当我们使用两个应用程序来