QT5开发笔记(七)--读写注册表及INI配置文件
INI文件读写操作:
# include <QSettings>
QString str;
// 打开INI配置文件(指定为IniFormat格式)
QSettings iniTest("E:\\test.ini",QSettings::IniFormat);
添加修改键值: 如果键值/节点不存在则添加,/后第一个值表示结点名称
iniTest.setValue("/IP/ipv4","192.168.10.150");
[IP]
ipv4=192.168.10.150
删除键值: 当结点下的最后一个键值对被删除后,结点也会被删除
iniTest.remove("/IP/ipv4");
读键值: 直接指定路径,如果不存在,则返回默认值(可省略)
iniTest.Value("/IP/ipv4", "Error").toString();
遍历读键值
// 获取节点列表
QStringList groupList = iniTest.childGroups();
// 遍历节点
foreach(QString group,groupList)
{
iniTest.beginGroup(group);
ui->textBrowser->append(group);
// 获取当前结点下的键值列表
QStringList keyList = iniTest.childKeys();
// 遍历列表
foreach(QString key,keyList)
{
// 读取键值
str = key + "="+tr(iniTest.value(key).toString().toStdString().c_str());
ui->textBrowser->append(str);
}
iniTest.endGroup();
}
注册表操作
打开注册表(指定为NativeFormat格式)
QSettings reg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP",QSettings::NativeFormat);
获取当前路径下的项目列表:
// 获取当前路径下的项目列表
QStringList groupsList=reg.childGroups();
// 遍历列表
foreach(QString group,groupsList)
{
ui->comboBox->addItem(group);
reg.beginGroup(group); // 开始操作本项目(切换路径)
// 在此插入其他操作
reg.endGroup(); // 离开当前项目,返回上级
}
获取当前路径下的键值列表:*
// 获取当前路径下的键值列表(不包含子项)
QStringList keyList = reg.childKeys();
// 获取当前路径下的键值列表(包含子项)
// QStringList keyList = reg.allKeys();
foreach(QString key,keyList)
{
ui->textBrowser->append(key + " = " + reg.value(key).toString());
}
foreach(QString group,groupsList)
{
ui->comboBox->addItem(group);
}
删除键值: 需要以管理员身份运行
reg.remove("Serial1");
注意事项:
QT5不支持带/的键名操作(可以读出键名,但不能通过键名取键值),需要通过WinAPI来实现;
只支持字符串,32bit及64bit类型的值,其他类型读出为空,WinAPI可以读出所有类型。
WinAPI示例:
#include <qt_windows.h>
QSettings reg("HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM",QSettings::NativeFormat);
HKEY hKey;
//打开启动项Key
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
{
qDebug() << "windows api read reg failed!";
}
else{
qDebug() << "windows api read reg success";
}
//for(int i = 0; i < reg.childKeys().size(); ++i)
//{
// QString key = reg.childKeys().at(i);
QStringList keyList = reg.childKeys();
foreach(QString key , keyList)
{
DWORD dwSize = 1024;
DWORD dwType = REG_DWORD;
WCHAR buf[1024];
QString backslash_key = key.replace(QChar('/'), QChar('\\'));
//char * 转换为 wchar_t * 类型
const wchar_t * w_key = reinterpret_cast<const wchar_t *>(backslash_key.utf16());
DWORD dwRet = RegQueryValueEx(hKey, w_key, NULL, &dwType, (LPBYTE)(&buf), &dwSize);
if (ERROR_SUCCESS != dwRet)
{
qDebug() << "RegQueryValueEx failed " << dwRet;
break;
}
else
{
if(dwType == REG_SZ) //字符串类型
{
QString strMessage = QString::fromUtf16(reinterpret_cast<const ushort *>(buf), dwSize/2 - 1);
qDebug() << "dwSize is: " << dwSize << "value is: " << strMessage;
}
else if(dwType == REG_BINARY)
{
qDebug() << "REG_BINARY dwSize is" << dwSize;
}
else if(dwType == REG_QWORD)
{
qDebug() << "REG_DWORD value = " << reinterpret_cast<const qint32 *>(buf);
}
else if(dwType == REG_QWORD)
{
qDebug() << "REG_QWORD value = " << reinterpret_cast<const qint64 *>(buf);
}
else
{
qDebug() << "dwType ==" << dwType << "dwSize = " << dwSize;
// 通过dwSize获取数据长度,数据全在buf里
}
}
}
RegCloseKey(hKey);
1.reinterpret_cast<const qint32 > 用于强制转换,相当于(qint32*),但直接用指针强制转换的话,qt5编译器会抱怨。
2.部分文档要求在工程文件中加入LIBS += -lAdvapi32静态库,实际测试不加入也可以正常编译运行,如果有问题就加上去。
3.WinAPI会造成系统依赖,但是....., 除了Windows,还有谁会用到注册表呢?