QSettings 是 PySide6 中用于持久化存储设定的类,会自动将应用的配置数据保存到系统对应位置(Windows 注册表、macOS/iOS 的 plist 文件、Linux 的配置文件),无需手动管理文件路径。QSettings 的核心价值是“跨平台 + 简化持久化存储”,核心特点可概括为 3 点:
- 用途:专门存储应用的配置数据(如窗口大小、用户偏好、登录状态等),程序重启后能恢复这些设定,避免重复配置;
- 跨平台自动适配:无需写平台判断代码,它会根据系统自动选择存储位置(Windows 写注册表、macOS/iOS 存 plist、Linux 存标准配置目录文件),开发者不用关心 “文件放哪”;
- 使用便捷:以 “键值对(key-value)” 方式读写数据,支持字符串、数字、布尔值等常见类型,无需手动处理文件创建、读写、解析(比如不用自己写 json/xml 读写逻辑)。
- 以QMainWindow为例介绍QSettings的简单用法:
QMainWindow 提供了以下方法来实现:
方法 | 作用 |
saveGeometry() | 保存窗口的几何状态(位置、大小、是否最大化 / 最小化),返回 QByteArray 类型 |
saveState() | 保存窗口的布局状态(工具栏位置、停靠窗口位置 / 状态、菜单栏可见性等),返回 QByteArray 类型 |
restoreGeometry(QByteArray) | 恢复窗口几何状态 |
restoreState(QByteArray) | 恢复窗口布局状态 |
import sys from PySide6.QtWidgets import ( QApplication, QMainWindow, QTextEdit, QDockWidget, QLabel, QWidget, QVBoxLayout ) from PySide6.QtCore import ( QSettings, QByteArray, Qt, QCoreApplication ) # 全局配置:统一组织名/应用名(必须和保存时一致) ORG_NAME = "MyCompany" APP_NAME = "DockRestoreApp" class MainWindow(QMainWindow): def __init__(self): super().__init__() # 1. 先初始化所有UI部件(包括停靠窗口、工具栏) self.init_base_ui() self.init_dock_widgets() # 2. 后恢复窗口状态(关键顺序) self.restore_window_state() def init_base_ui(self): """初始化基础UI(中央部件、窗口属性)""" self.setWindowTitle("停靠窗口状态恢复示例") # 中央部件(必须设置) central_widget = QTextEdit() central_widget.setPlaceholderText("中央编辑区") self.setCentralWidget(central_widget) def init_dock_widgets(self): """初始化停靠窗口(必须设置唯一ObjectName)""" # 左侧停靠窗口(核心:设置唯一ObjectName,Qt靠这个识别停靠窗口) left_dock = QDockWidget("左侧面板", self) left_dock.setObjectName("LeftDockWidget") # 必须! # 停靠窗口内容 dock_content = QWidget() dock_layout = QVBoxLayout(dock_content) dock_layout.addWidget(QLabel("左侧停靠窗口内容")) dock_layout.addStretch() left_dock.setWidget(dock_content) # 设置停靠规则 left_dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) left_dock.setFeatures(QDockWidget.DockWidgetMovable | QDockWidget.DockWidgetClosable) # 添加到主窗口 self.addDockWidget(Qt.LeftDockWidgetArea, left_dock) # 可选:添加第二个停靠窗口测试 right_dock = QDockWidget("右侧面板", self) right_dock.setObjectName("RightDockWidget") # 必须! right_dock.setWidget(QLabel("右侧停靠窗口内容")) self.addDockWidget(Qt.RightDockWidgetArea, right_dock) def restore_window_state(self): """恢复窗口状态(几何+布局)""" # 初始化QSettings(强制INI格式,方便调试,可选) QSettings.setDefaultFormat(QSettings.IniFormat) settings = QSettings(ORG_NAME, APP_NAME) # 1. 恢复窗口几何状态(位置、大小) geometry = settings.value("geometry", QByteArray()) if isinstance(geometry, str): geometry = QByteArray.fromBase64(geometry.encode()) if not geometry.isEmpty(): # 恢复失败则用默认大小 if not self.restoreGeometry(geometry): self.resize(1000, 700) # 2. 恢复窗口布局状态(核心:停靠窗口/工具栏) window_state = settings.value("windowState", QByteArray()) if isinstance(window_state, str): window_state = QByteArray.fromBase64(window_state.encode()) if not window_state.isEmpty(): # 关键:指定版本号(默认0,若布局变更可升级版本) self.restoreState(window_state, version=0) def closeEvent(self, event): """窗口关闭时保存状态""" settings = QSettings(ORG_NAME, APP_NAME) # 保存几何状态 settings.setValue("geometry", self.saveGeometry()) # 保存布局状态(包含停靠窗口) settings.setValue("windowState", self.saveState(version=0)) # 立即同步到磁盘(避免延迟) settings.sync() # 允许关闭 event.accept() if __name__ == "__main__": # 全局设置组织名/应用名(QSettings依赖) QCoreApplication.setOrganizationName(ORG_NAME) QCoreApplication.setApplicationName(APP_NAME) app = QApplication(sys.argv) window = MainWindow() window.show() sys.exit(app.exec())- 关键细节与注意事项
1. QSettings的存储路径
默认情况下,QSettings 会根据系统自动选择存储位置:
- Windows:HKEY_CURRENT_USER\Software\MyCompany\MyApp(注册表)
- macOS:~/Library/Preferences/com.MyCompany.MyApp.plist
- Linux:~/.config/MyCompany/MyApp.conf
如果想强制保存为INI 文件(便于调试),可在初始化 QApplication 后设置:
QSettings.setDefaultFormat(QSettings.IniFormat) # 自定义INI文件路径 settings = QSettings("my_app_config.ini", QSettings.IniFormat)2.数据类型兼容问题
- saveGeometry()/saveState() 返回 QByteArray,但 QSettings 存储时可能自动转为字符串(Base64 编码);
- 读取时需判断类型,若为字符串则转回 QByteArray(如示例中所示),否则 restoreGeometry 会失效。
3.版本兼容(重要)
如果后续修改了窗口布局(如新增 / 删除停靠窗口、工具栏),restoreState 可能会失败。解决方法:
# 保存时指定版本号 self.saveState(1) # 版本号1 # 恢复时指定版本号(兼容旧版本) self.restoreState(window_state, 1)4.避免恢复异常
- 若保存的状态损坏(如手动修改配置文件),restoreGeometry/restoreState 会返回 False,可增加判断:
if not self.restoreGeometry(geometry): self.resize(800, 600) # 恢复失败则使用默认大小5.清除保存的状态
如需重置窗口状态,可删除 QSettings 中的对应键:
settings = QSettings("MyCompany", "MyApp") settings.remove("geometry") settings.remove("windowState") settings.sync() # 立即同步到磁盘- 扩展用法
1.保存更多自定义状态
除了窗口状态,还可保存用户偏好(如字体、主题、上次打开的文件路径):
# 保存 settings.setValue("last_open_file", "/home/user/test.txt") settings.setValue("font_size", 14) settings.setValue("dark_mode", True) # 读取 last_file = settings.value("last_open_file", "") font_size = int(settings.value("font_size", 12)) dark_mode = settings.value("dark_mode", False, type=bool)2.全局共享 QSettings
在大型应用中,可创建全局 QSettings 实例,避免重复初始化:
# 全局配置 class AppSettings: _instance = None @classmethod def get_instance(cls): if cls._instance is None: cls._instance = QSettings("MyCompany", "MyApp") return cls._instance # 使用 settings = AppSettings.get_instance() settings.setValue("geometry", self.saveGeometry())