在通常情况下,用户使用一个软件的时候,期望保存一些数据状态,比如窗口的大小和位置,主题,选项,最近操作过的文件等等信息,在下一次启动软件的时候就自动加载这些信息,让软件恢复到上一次退出时的状态。在Windows系统中,这些信息通常存储在系统注册表中,在macOS和iOS则存储在属性列表中。在Unix系统上,在没有标准情况下,许多应用都使用INI文件来保存配置信息。 QSettings就是围绕不同的系统做了技术上的抽象,使开发者可以轻松实现在不同系统间可移植的方式来保存和恢复应用程序设置。同时QSetting还可以支持自定义存储格式来保存和恢复应用程序的设置。

QSettings简介

QSettings类提供一种与平台无关的应用程序设置的保存和恢复技术。可以用下面的方式创建QSettings对象。

方式一: 传递给QSettings两个参数,第一个为公司或者组织的名称(如MySoft),第二个是应用程序的名称(如 MyProgram),创建一个QSettings对象:

self.settings = QSettings('MySoft', 'MyProgram')

说明,在Windows下同下,这种方式信息写在注册表中。

方式二:指定配置文件名和配置文件格式的方式来创建,如下面的语句将以ini文件的格式创建一个名为config.ini的配置信息文件:

self.settings = QSettings('config.ini', QSettings.IniFormat)

使用函数setValue()来存储数据,如果已经存在相同的键值,那么新设置的值将覆盖就的设置值。为了保证效率,所做的更改有可能不会马上存储到文件中,使用sync()函数可以保证设置同步存储到文件中。函数 value()返回存储的键值。

键(key)可以包含任何Unicode字符。Windows注册表和INI文件使用不区分大小写的键,而macOS和iOS上的CFPreferences API使用不区分大小写的键。为避免可移植性问题,请遵循以下简单规则:

  • 始终使用相同的大小写引用相同的键。例如,如果在代码中的某个地方将键称为“text fonts”,则不要在其他地方将使用“Text Fonts”来引用。
  • 除大小写外,请避免使用相同的键名。例如,如果您有一个名为“ MainWindow”的键,请不要尝试将另一个键另存为“ mainwindow”。
  • 在节或键名中不要使用斜杠(“ /”和“ ”);反斜杠字符用于分隔子键。在Windows上,QSettings将“ ”转换为“ /”,从而使它们相同。

可以使用'/'字符作为分隔符来形成分层键,类似于Unix文件路径。例如:

self.settings.setValue("mainwindow/size", self.win.size()self.settings.setValue("mainwindow/fullScreen", self.win.isFullScreen()self.settings.setValue("outputpanel/visible", self.panel.isVisible()

如果要保存或者读取很多具有相同分组的设置,则可以使用beginGroup()指定分组前缀,并在最后调用endGroup()。使用分组机制,演示上面的示例代码如下:

self.settings.beginGroup("mainwindow");self.settings.setValue("size", self.win->size())self.settings.setValue("fullScreen", self.win.isFullScreen())self.settings.endGroup(); self.settings.beginGroup("outputpanel");self.settings.setValue("visible", self.panel.isVisible())self.settings.endGroup()

演示

在前面notepay.py的基础上,添加了三个函数initRecentFile(), updateRecentFileMneu() 和updateRecentFiles(),演示了使用QSettings为程序添加最近列表的功能。 完整代码如下:

import sysfrom PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtCore import Qt, QSettingsfrom PyQt5.QtWidgets import (QApplication, QMainWindow, QMenuBar, QMenu,                              QAction, QPlainTextEdit, QStyle, QFileDialog,                             QMessageBox, QToolBar, QStatusBar, QLabel) class DemoNotepad(QMainWindow):    def __init__(self, parent=None):        super(DemoNotepad, self).__init__(parent)                       # 设置窗口标题        self.setWindowTitle('实战 Qt for Python: QSettings 演示-记事本')              # 设置窗口大小        self.resize(480, 360)                self.path = None              self.initUi()            def initUi(self):                 #设置一个文本编辑器作为中心小部件        self.txtEditor = QPlainTextEdit(self)          self.setCentralWidget(self.txtEditor)                self.initRecentFileList()                #创建菜单条和工具条使用的Action         self.initActions()           #初始化菜单条             self.initMenuBar()        #初始化化工具条        self.initToolBar()        #初始化状态条        self.initStatusBar()     def initActions(self):        style = QApplication.style()                #新建文件        self.aFileNew = QAction('新建(&N)', self)        #添加一个图标        self.aFileNew.setIcon(style.standardIcon(QStyle.SP_FileIcon))        #添加快捷键        self.aFileNew.setShortcut(Qt.CTRL + Qt.Key_N)        self.aFileNew.setToolTip('新建一个文本文件')        self.aFileNew.triggered.connect(self.onFileNew)                  #打开文件        self.aFileOpen = QAction('打开(&O)...', self)        self.aFileOpen.setIcon(style.standardIcon(QStyle.SP_DialogOpenButton))        self.aFileOpen.setShortcut(Qt.CTRL + Qt.Key_O)        self.aFileOpen.setToolTip('打开一个文本文件')        self.aFileOpen.triggered.connect(self.onFileOpen)                #保存        self.aFileSave = QAction('保存(&S)', self)         self.aFileSave.setIcon(style.standardIcon(QStyle.SP_DialogSaveButton))         self.aFileSave.setShortcut(Qt.CTRL + Qt.Key_S)        self.aFileSave.setToolTip('保存文本文件')        self.aFileSave.triggered.connect(self.onFileSave)                #另存为        self.aFileSaveAs = QAction('另存为(&A)...', self)        self.aFileSaveAs.triggered.connect(self.onFileSaveAs)                  #退出        self.aFileExit = QAction('退出(&X)', self)         self.aFileExit.triggered.connect(self.close)                 #撤销编辑        self.aEditUndo = QAction('撤销(&U)',self)        self.aEditUndo.setShortcut(Qt.CTRL + Qt.Key_Z)        self.aEditUndo.triggered.connect(self.txtEditor.undo)                #恢复编辑        self.aEditRedo = QAction('恢复(&R)', self)        self.aEditRedo.setShortcut(Qt.CTRL + Qt.Key_Y)        self.aEditUndo.triggered.connect(self.txtEditor.redo)                #剪切操作        self.aEditCut = QAction('剪切(&T)', self)        self.aEditCut.setShortcut(Qt.CTRL + Qt.Key_X)        self.aEditCut.triggered.connect(self.txtEditor.cut)          #复制操作        self.aEditCopy = QAction('复制(&C)', self)        self.aEditCopy.setShortcut(Qt.CTRL + Qt.Key_C)        self.aEditCopy.triggered.connect(self.txtEditor.copy)         #粘贴操作        self.aEditPaste = QAction('粘贴(&P)', self)        self.aEditPaste.setShortcut(Qt.CTRL + Qt.Key_V)        self.aEditPaste.triggered.connect(self.txtEditor.paste)         #删除操作        self.aEditDel = QAction('删除(&L)', self)        self.aEditDel.setShortcut(Qt.Key_Delete)        self.aEditDel.triggered.connect(self.onEditDelete)         #全选操作        self.aEditSelectAll = QAction('全选(&A)', self)        self.aEditSelectAll.setShortcut(Qt.CTRL + Qt.Key_A)        self.aEditSelectAll.triggered.connect(self.txtEditor.selectAll)         self.aFmtAutoLine = QAction('自动换行(&W)', self)        self.aFmtAutoLine.setCheckable(True)        self.aFmtAutoLine.setChecked(True)        self.aFmtAutoLine.triggered[bool].connect(self.onFormatAutoLine)         self.aHelpAbout = QAction('关于(&A)...', self)        self.aHelpAbout.triggered.connect(self.onHelpAbout)     def initMenuBar(self):        menuBar = self.menuBar()               self.fileMenu = menuBar.addMenu('文件(&F)')        editMenu = menuBar.addMenu('编辑(&E)')        formatMenu = menuBar.addMenu('格式(&O)')        helpMenu = menuBar.addMenu('帮助(&H)')                # ==== 文件操作部分 ==== #         self.fileMenu.addAction(self.aFileNew)           self.fileMenu.addAction(self.aFileOpen)                   self.fileMenu.addAction(self.aFileSave)                self.fileMenu.addAction(self.aFileSaveAs)              self.fileMenu.addSeparator()                self.fileMenu.addAction(self.aFileExit)                self.updateRecentFileMenu()                # ==== 编辑部分 ==== #        editMenu.addAction(self.aEditUndo)        editMenu.addAction(self.aEditRedo)        editMenu.addSeparator()                editMenu.addAction(self.aEditCut)        editMenu.addAction(self.aEditCopy)        editMenu.addAction(self.aEditPaste)        editMenu.addAction(self.aEditDel)        editMenu.addSeparator()        editMenu.addAction(self.aEditSelectAll)        #当编辑栏的菜单对象被点击时, 在状态栏显示信息        editMenu.triggered[QAction].connect(self.onProcessTrigger)                # ==== 格式设置部分 ==== #        formatMenu.addAction(self.aFmtAutoLine)                # ==== 帮助部分 ==== #        helpMenu.addAction(self.aHelpAbout)                    def initToolBar(self):        toolBar = self.addToolBar('')           toolBar.addAction(self.aFileNew)        toolBar.addAction(self.aFileOpen)        toolBar.addAction(self.aFileSave)            def initStatusBar(self):        self.statusBar = QStatusBar(self)        #添加一个显示永久信息的标签控件        self.info = QLabel(self)        self.info.setText('实战 Qt for Python')        self.info.setAlignment(Qt.AlignRight)        self.statusBar.addPermanentWidget(self.info)        self.setStatusBar(self.statusBar)                   def msgCritical(self, strInfo):        dlg = QMessageBox(self)        dlg.setIcon(QMessageBox.Critical)        dlg.setText(strInfo)        dlg.show()            def onFileNew(self):        self.txtEditor.clear()            def onFileOpen(self):        path,_ = QFileDialog.getOpenFileName(self, '打开文件', '', '文本文件 (*.txt)')        if path:            if self.loadFile(path):                #添加到最近打开的菜单列表中                self.updateRecentFiles(path)          #加载文件              def loadFile(self, path):        try:            with open(path, 'r') as f:                text = f.read()        except Exception as e:            self.msgCritical(str(e))            return False        else:            self.path = path            self.txtEditor.setPlainText(text)            self.statusBar.showMessage('打开文件 ' + path, 5000)            return True                            def onFileSave(self):        if self.path is None:            return self.onFileSaveAs()        self._saveToPath(self.path)            def onFileSaveAs(self):        path,_ = QFileDialog.getSaveFileName(self, '保存文件', '', '文本文件 (*.txt)')        if not path:            return        self._saveToPath(path)                    def _saveToPath(self, path):        text = self.txtEditor.toPlainText()        try:            with open(path, 'w') as f:                f.write(text)        except Exception as e:            self.msgCritical(str(e))        else:            self.path = path                def onEditDelete(self):        tc = self.txtEditor.textCursor()        #tc.select(QtGui.QTextCursor.BlockUnderCursor) 这样删除一行        tc.removeSelectedText()        def onFormatAutoLine(self, autoLine):        if autoLine:            self.txtEditor.setLineWrapMode(QPlainTextEdit.WidgetWidth)        else:            self.txtEditor.setLineWrapMode(QPlainTextEdit.NoWrap)        def onHelpAbout(self):        QMessageBox.information(self, '实战 Qt for Python', 'PyQt5实现的文本编辑器演示版')            def onProcessTrigger(self, action):        self.statusBar.showMessage(action.text() + ' 菜单项被点击了', 3000)            #初始化最近文件列表信息    def initRecentFileList(self):        #创建一个配置对象        #方式一:        #self.settings = QSettings('Qt-for-Python', 'My notePad')        #方式二:        self.settings = QSettings('config.ini', QSettings.IniFormat)                #加载最近文件        self.recentFiles=self.settings.value('FileList/recentFiles') or []                #添加最近文件菜单行为        self.maxNumRecentFiles = 4  #最多四个最近的文件        self.recentFileActions = []          for i in range (self.maxNumRecentFiles):            self.recentFileActions.append(QAction(self))        #更新最近文件列表菜单    def updateRecentFileMenu(self):        #先移除添加的行为        for action in self.recentFileActions:            self.fileMenu.removeAction(action)                    #移除退出菜单项        self.fileMenu.removeAction(self.aFileExit)        #移除多余的                #最近文件        for i, fname in enumerate(self.recentFiles):            action = self.recentFileActions[i]            action.setText(fname)            action.setToolTip('最近打开的文件')            action.setData(fname) #保存数据            action.triggered.connect(self.loadRecentFile)            self.fileMenu.addAction(action)                    #恢复退出菜单项        self.fileMenu.addSeparator()        self.fileMenu.addAction(self.aFileExit)                #更新最近文件    def updateRecentFiles(self, fname):        if fname not in self.recentFiles:            self.recentFiles.insert(0, fname)            if len(self.recentFiles) > self.maxNumRecentFiles:                self.recentFiles.pop()                        #更新菜单            self.updateRecentFileMenu()                        #保存更新后最近菜单列表            self.settings.setValue('FileList/recentFiles', self.recentFiles)                def loadRecentFile(self):        sender = self.sender()        if isinstance(sender, QAction):            fname = sender.data() #取出保存的数据            self.loadFile(fname)                     if __name__ == '__main__':    app = QApplication(sys.argv)    window = DemoNotepad()    window.show()    sys.exit(app.exec())     

演示结果如下图:

QSettings测试

本文知识点

  • 提供一种与平台无关的应用程序设置的保存和恢复技术。
  • 在菜单条中插入和清除菜单项。
  • 在QAction中保存数据。
  • 使用QSettings实现最近打开文件列表。

前一篇:实战PyQt5: 124-在应用中访问系统的标准路径


请多多关注,评论,收藏,点赞,和转发。

qss qmenu 设置icon位置大小_实战PyQt5: 125-使用配置文件来保存和恢复应用的设置...相关推荐

  1. winform listview 设置选中项 图片_实战PyQt5: 069-MV框架中的项视图拖放功能

    模型-视图框架完全支持Qt的基本拖放操作,列表.树形和表格部件中的项可以在视图间拖动,数据可以以MIME类型的格式进行导入和导出 Qt提供的标准视图自动支持在视图内部的拖放,其中的项可以被移动以改变显 ...

  2. button 样式_实战PyQt5: 111-可以使用QSS样式表的部件

    可以使用QSS样式表的部件 QSS样式表支持各种部件,属性,伪状态和子控件,从而可以实现定制部件的外观,下面我们将详细列出可以使用QSS样式表的部件: QAbstractScrollArea:所有派生 ...

  3. qchart 设置线颜色_实战PyQt5: 137-QChart图表之散点图

    散点图(scatter chart)将序列显示为一组点.值由点在图表中的位置表示.类别由图表中的不同标记表示.散点图通常用于比较跨类别的聚合数据.在QChart中,使用类QScatterSeries创 ...

  4. qchart 坐标轴设置_实战PyQt5: 156-QChart图表之更换图表主题

    图表主题 QChart定义了多种图表主题,可以创建不同风格的图表显示,在调整图表主题风格的时候,为了使整个应用的风格看起来更和谐一致,一般要使用应用程序的背景调色板来调整应用的颜色以适配图表所选的主题 ...

  5. qtabwidget的图标_实战PyQt5: 050-选项卡控件QTabWidget

    QTabWidget简介 在GUI应用软件中,多页面的切换的使用范围十分广泛,在操作过程中,用户使用鼠标点击不同的标题栏就可以方便展示不同页面的内容,众多界面共用一块显示区域,在有限的就显示区域中可以 ...

  6. pyqt 子窗口控制主窗口绘图_实战PyQt5: 005-主窗口QMainWindow

    QMainWindow简介 在桌面应用中,一个应用软件通常都会包含一个主窗口,主窗口是承载所有控件的窗体, 在PyQt5中常用的主窗体有两种QMainWindow和QDialog,他们也都继承自QWi ...

  7. chart.js 饼图显示百分比_实战PyQt5: 135-数据可视化之QChart绘制饼图

    饼图是数据可视图表的基本类型,在QChart中,QPieSeries, QPieSlice处理饼图的绘制. QPieSeries QPieSeries类以饼图形式显示数据.饼图系列由定义为QPieSl ...

  8. openopc.opcerror: dispatch: 无效的类字符串_实战PyQt5: 064-MV框架中的Model类

    模型(Model)简介 在Model-View框架中,模型(Model)为视图(View)和委托(Delegate)使用数据提供了标准接口.大多数情况下模型中并不真正存储数据(如果只有少量的数据,可以 ...

  9. pyqt5从子目录加载qrc文件_实战PyQt5: 045-添加资源文件

    添加资源文件 在使用PyQt进行图形界面开发的时候不免要用到一些外部资源,比如图片,qss配置文件等.在前面代码中,遇到这类问题,我们使用绝对路径的方式来解决,这种方式,本身有其不方便之处(比如,调整 ...

最新文章

  1. 不要痴迷蓝牙耳机了,出门选这个准没错,99W+人的选择
  2. java 与sql设置排序方法是_恕我直言你可能真的不会java第7篇:像使用SQL一样排序集合...
  3. Learn Python The Hard Way(20)
  4. asp.net服务器控件与html服务器控件的区别
  5. CRM_REPORT_RF_AUTH_OBJ_ORD_PR
  6. ubuntu修改启动项等待时间、修改启动项顺序、更改启动内核
  7. 【板栗糖GIS】如何将3dmax数据导入到超图软件中
  8. 二次规划--积极集法(active set method)
  9. GRE_××× 配置(建议选择Cisco2811路由器)
  10. python实现爬取网易云音乐评论,并且将评论信息存储到pymysql
  11. DeepMind AI碾压《星际争霸2》人类职业玩家 但它还不完美
  12. 微信小程序开发《6 .框架之逻辑层》
  13. java PDF转换图片(IMG)
  14. OSPF的NBMA环境建立邻居及排错,理论+实战讲解,干货分享
  15. c++: internal compiler error: 已杀死 (program cc1plus)的解决方法
  16. 汇编语言六 报数出列设有n(设为17)个人围坐在圆桌周围,按顺时针给他们编号(1,2,~~~,n),从第1个人开始顺时针方向+1报数,当报数到m(设为11)时,该人出列
  17. HTML5 - 限制input file 可选择的文件类型
  18. spring--mvc用戶注册用户名验重
  19. 计算机都学什么数学,数学在计算机起到什么作用
  20. Microsoft Visual Basic for Applications 编译错误:更新 Declare 语句

热门文章

  1. UI设计实用素材|网页陆地页面的业务和发展概念插图
  2. 【超详细】在Linux上远程登录遇到的若干问题及解决方法(一)
  3. ps css html,用ps两分钟做个xhtml+css的网站首页
  4. python3字节转化字符_浅谈 Python3 中对二进制数据 XOR 编码的正确姿势
  5. #include_next
  6. pytorch实现人脸识别_PyTorch实现,GitHub4000星:这是微软开源的计算机视觉库
  7. 菜单向上拉html,模拟select控件,CSS上拉菜单
  8. html代码自动提示语怎么设置,怎么为Html的Select加提示语_html
  9. 计算机应用段落设置,计算机应用操作基础.docx
  10. html5 平移,Html5 canvas绘图旋转和平移