存储原理:基于键值对的持久化存储
HKEY_CURRENT_USER\Software\[组织名]\[应用名]
~/Library/Preferences/[组织名].[应用名].plist
~/.config/[组织名]/[应用名].conf
基础代码框架:
from PySide6.QtCore import QSettings
# 初始化(macOS需要特殊处理)
settings = QSettings("MyCompany", "MyApp") # 组织名/应用名
# 写入配置
settings.setValue("Window/Size", self.size())
# 读取配置
window_size = settings.value("Window/Size", defaultValue=QSize(800, 600))
支持类型:int
, str
, bool
, QColor
, QFont
, QByteArray
等
特殊类型处理案例:
# 存储颜色配置
settings.setValue("Theme/Color", QColor(255, 0, 0))
# 读取颜色(需显式转换)
color = settings.value("Theme/Color", QColor(255, 255, 255))
if isinstance(color, str): # 处理INI格式的字符串存储
color = QColor(color)
类型转换表:
存储类型 | 读取类型 | 转换方法 |
---|---|---|
QColor | str | name() |
QFont | str | toString() |
QDate | str | toString(Qt.ISODate) |
方法1:路径分层
settings.setValue("UserPrefs/Editor/FontSize", 12)
settings.setValue("UserPrefs/Editor/Theme", "dark")
方法2:显式分组(推荐)
settings.beginGroup("Network")
settings.setValue("ProxyEnabled", True)
settings.setValue("Timeout", 30)
settings.endGroup()
多级分组嵌套:
settings.beginGroup("MainWindow")
settings.beginGroup("Toolbars")
settings.setValue("FileToolbar/Visible", True)
settings.endGroup()
settings.endGroup()
路径差异处理:
# 通用初始化方法
if sys.platform == "darwin":
QSettings.setDefaultFormat(QSettings.NativeFormat)
else:
QSettings.setDefaultFormat(QSettings.IniFormat)
平台特定配置示例:
# Windows注册表特殊处理
if sys.platform == "win32":
settings = QSettings(
QSettings.NativeFormat,
QSettings.UserScope,
"MyCompany",
"MyApp/Win32Special"
)
1. 配置版本迁移
version = settings.value("ConfigVersion", 1)
if version < 2:
# 迁移旧版配置
old_value = settings.value("OldKey")
settings.setValue("NewKey", convert_value(old_value))
settings.remove("OldKey")
settings.setValue("ConfigVersion", 2)
2. 配置项监听(QObject绑定)
class ConfigManager(QObject):
def __init__(self):
super().__init__()
self.settings = QSettings()
self.settings.valueChanged.connect(self.on_config_changed)
@Slot(str)
def on_config_changed(self, key):
print(f"配置变更:{key} => {self.settings.value(key)}")
# 错误方式
timeout = settings.value("Timeout") or 30 # 类型不安全
# 正确方式
timeout = settings.value("Timeout", 30, type=int)
settings.beginWriteArray("RecentFiles")
for i, path in enumerate(recent_files):
settings.setArrayIndex(i)
settings.setValue("Path", path)
settings.endArray()
# 删除单个键
settings.remove("ObsoleteKey")
# 清除整个分组
settings.beginGroup("TempData")
settings.remove("") # 删除当前分组所有内容
settings.endGroup()
1. 实时监控工具:
regedit
查看注册表# Linux查看配置
tail -f ~/.config/MyCompany/MyApp.conf
# macOS查看plist
plutil -p ~/Library/Preferences/com.MyCompany.MyApp.plist
2. 配置导出/导入:
# 导出配置到文件
settings = QSettings()
settings.saveToFile("backup.ini", QSettings.IniFormat)
# 从文件导入
with open("backup.ini", "r") as f:
settings.loadFromData(f.read().encode(), QSettings.IniFormat)
问题1:配置项存在但读取返回None
# 错误原因:类型不匹配
settings.setValue("RetryCount", "5") # 存储为字符串
count = settings.value("RetryCount", 0, type=int) # 正确转换
问题2:跨平台配置同步
# 使用通用格式强制同步
settings = QSettings("MyApp.ini", QSettings.IniFormat)
settings.setValue("CrossPlatform/Data", "统一格式")
问题3:配置项加密
# 简单加密示例
from cryptography.fernet import Fernet
key = Fernet.generate_key()
cipher = Fernet(key)
encrypted = cipher.encrypt(b"SensitiveData")
settings.setValue("Secure/Password", encrypted.decode())
# 解密读取
decrypted = cipher.decrypt(settings.value("Secure/Password").encode())
通过结合这些实践方案,开发者可以构建健壮的配置管理系统,覆盖从基础存储到企业级应用的各种需求场景。实际开发中建议封装独立的配置管理类,集中处理类型转换、版本迁移、加密解密等通用逻辑。