【问题标题】:whats the advantage of QSettings over just using a dict?QSettings 与仅使用字典相比有什么优势?
【发布时间】:2019-12-13 00:45:50
【问题描述】:

QSettings 在 C++ 中似乎是一个很棒的东西,它本质上是一个灵活的哈希表,其中键是字符串,值是 QVariant,所以它可以是相当多的类型。然而,在 Python 中我们已经有了这个,它是一个字典。所以我问,在 PyQt 中使用 QSettings 比仅使用 dict 有什么优势?

编辑: 更简洁地说,我使用 QSettings 对象将特定设置分配给特定键的每一行,我都可以用字典做同样的事情。是的,QSettings 有一些细节,比如转换为 ini 文件,但我可以使用 json 模块将 dict 存储到文件中,并使用相同的代码行数。例如,就 QSettings 提供的能力而言,我试图理解为什么人们会使用它而不是仅仅使用 dict 和 json 模块。我已经仔细阅读了文档以了解 QSettings 提供的东西,没有任何东西对我来说是一个非常棒的功能,所以我基本上是在问,你认为 QSettings 最有益的功能是什么,为什么它优于使用一个 dict + json 模块

【问题讨论】:

  • 正如文档所述,它们不是一回事——字典在内存 (RAM) 中,而 QSettings 存储在硬盘驱动器上,简而言之,这是您的主要和最重要的区别,并且基于这个列表还在继续。
  • 如果我有一个代表设置的字典,我可以轻松地使用 json 模块将设置存储到文件中。我意识到 QSettings 有一些用于将设置存储到 ini 文件的选项。在比较方面,我真的不认为 QSettings 在这里有优势,我认为它们在功能奇偶性方面是平等的
  • @KevinS 那么您可能会问,JSON 格式(不是 json 模块)和 QSettings 有什么区别?
  • @eyllanesc 不一定。从实现的角度来看,我知道我需要将所有小部件的状态存储在内存中,然后存储到文件中,然后在另一个时间我需要将状态从文件加载到内存中,最后加载到小部件中。在我看来,QSettings 并不优于 python dict + json 模块。如果我特别知道我会有嵌套结构,那么 QSetting 模块只支持开箱即用的 ini 文件,其他任何东西(例如 yaml 或 json),我将不得不提供挂钩来实现它。这似乎并不优于仅使用 dict + json 模块
  • @KevinS 正如我在回答中指出的那样,一个或另一个类的选择具体取决于您的要求,没有一个是更好的,因为它们只是替代另一个选项的缺陷的替代品。

标签: python pyqt qsettings


【解决方案1】:

QSettings 不是容器,因此在 python 中它不等同于字典。 类似于 Qt/C++ 中的字典的东西可能是 QMap(显然有其局限性)。

QSettings 是一个允许您永久保存信息的类,也就是说,当应用程序重新打开时,即使该信息也可以访问,不像字典那样,当应用程序关闭时会丢失它保存的信息。

例如,让我们使用以下示例并运行几次:

字典:

d = {"foo": "bar"}
print(d)
# modify dictionary
d["foo"] = "rab"

输出:

{'foo': 'bar'}
{'foo': 'bar'}
{'foo': 'bar'}
{'foo': 'bar'}
{'foo': 'bar'}

QSettings

from PyQt5 import QtCore

settings = QtCore.QSettings("Foo", "Bar")
value = settings.value("value", 0, type=int)
print(value)
settings.setValue("value", value + 1)
settings.sync()

输出:

0
1
2
3
4

在第一种情况下,它不考虑程序的先前执行,但在第二种情况下。

总之,QSettings 允许您保存应用程序在再次运行时可以使用的信息,例如保存会话、权限等。

另外,QSettings 是一个抽象层,在多个平台上实现了之前的功能。


根据你指出的版本,我想你想将 QSettings 与 dict + json 模块进行比较。

嗯,选择取决于用户,但以下内容可以帮助您选择:

  • QSettings 支持存储许多原生 Qt 类,例如 QSize、QPoint 等,但使用 Json 时不支持它们。

所以最后 QSettings 是一个选项,在 Qt 世界中是独一无二的,但在 Python 世界中并不是独一无二的,因为还有其他类似 PyYAML(YAML)、ConfigParser(INI)、@987654326 @(XML) 等

【讨论】:

  • 我认为它仍然是一个容器,而是一个保存和读取文件的容器。当 QSettings 更新时,它将其设置保存到一个文件中,当程序重新启动时,QSettings 从一个文件中读取以初始化自身。在内存中,它充当哈希表(如果您查看源代码 QSettings 是 C++ Map)。
  • @Error-SyntacticalRemorse 该容器是否可以有很多定义,具体取决于所讨论的内容,例如检查stackoverflow.com/questions/11575925/…cplusplus.com/reference/stl
  • C++ Map 是一个基于这两个链接提供的定义的容器对象。虽然它不是Collections.abc.Container。如果你想深入了解它,那么普通的dict 不是 CPython 中的容器。
  • @Error-SyntacticalRemorse QSettings 可以是一个容器,但我认为严格来说你必须有一个内部容器来存储信息,直到它存储在持久内存中。如果我们只去语言定义,那么每个有容器的类也将是一个容器。
  • 您的编辑已经处于问题的风口浪尖,我很欣赏这种见解“QSettings 支持存储许多本机 Qt 类,例如 QSize、QPoint 等,但是使用 Json 它不支持它们。”这是一个很好的观点。
【解决方案2】:

来自Documentation

用户通常希望应用程序在会话中记住其设置(窗口大小和位置、选项等)。此信息通常存储在 Windows 上的系统注册表中,以及 macOS 和 iOS 上的属性列表文件中。在 Unix 系统上,在没有标准的情况下,许多应用程序(包括 KDE 应用程序)使用 INI 文本文件。

QSettings 是围绕这些技术的抽象,使您能够以可移植的方式保存和恢复应用程序设置。它还支持自定义存储格式。

QSettings 的 API 基于 QVariant ,允许您以最少的工作量保存大多数基于值的类型,例如 QString 、 QRect 和 QImage 。

因此,它实际上不仅仅是一个原始的dict 对象,它处理与在重新启动之间保存应用程序状态相关的常见任务。它实现了许多方便的methods 来实现这一点。

【讨论】:

  • 该页面上列出的 90% 或更多的方法与与容器的交互有关。我担心的是,在相同或更少的代码行中,我可以使用 dict + json 模块并实现相同的概念(在内存存储中轻松存储到磁盘然后重新加载)
  • 你当然可以做到。这个对象似乎是一个方便的实现,它减少了开发人员需要做的工作量。它还可能能够编码 json 模块无法开箱即用的 qt 对象。
  • 最后一行“可能能够编码 json 模块无法开箱即用的 qt 对象”正是我希望找到的类型。例如,如果 QSettings 模块能够开箱即用地知道如何仅根据小部件类型将所有状态存储在小部件上,那就太好了。如果存在这样的能力,它很容易胜过 dict+json
  • 它能够序列化大多数QVariant 对象,它们只是基于值的对象。读回它们并使用它们在 statrup 上配置小部件很方便。看到这个example。但是,文档中没有任何内容表明您可以直接保存任意小部件的所有属性。您仍然需要保存并重新加载该小部件的特定属性,并在启动时再次将它们传递给构造函数。
猜你喜欢
  • 2014-06-14
  • 2010-09-24
  • 2010-12-27
  • 2015-04-06
  • 2013-05-09
  • 2017-05-29
  • 2017-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多