在我的桌面应用中,我使用QSettings来保存各种应用程序值。例如,主表单位置,最近文档,连接参数以及一些改变应用程序行为方式的内容,例如“不再在信息对话框中显示此消息”。
我通常的处理方法是在应用程序启动时将所有设置读入结构或对象,并在应用程序关闭时保存它们。
我还有一个对话框,可以让我编辑设置对象中的许多值,并在对话框关闭时保存它们。
许多窗口和非可视对象都需要设置对象中的值。
这样做的最佳方式是什么?
我已经开始将设置对象作为主窗口的成员,但后来我遇到了其他窗口需要访问主窗口成员的问题。
我确实认为我可以在自己的cpp文件中创建设置对象,只需#include需要的地方。但我不确定这是否可能或它的语法。
此方案的最佳做法是什么?
答案 0 :(得分:6)
我建议始终使用QSettings,避免使用补充结构或类。您可以在主服务器中设置应用程序名称,组织名称和 organization domanin 。
来自QtDocs:
如果您在应用程序的许多地方使用QSettings,您可能希望使用QCoreApplication :: setOrganizationName()和QCoreApplication :: setApplicationName()指定组织名称和应用程序名称,然后使用默认的QSettings构造函数:< / p>
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
然后使用默认构造函数,您需要在其中加入属性:
QSettings settings;
QSettings对象可以在堆栈上或堆上创建(即使用new)。构造和销毁QSettings对象非常快。
您可以在程序中的任何位置设置设置:
如果已存在具有相同键的设置,则新值将覆盖现有值。为了提高效率,可能无法立即将更改保存到永久存储中。 (您始终可以调用sync()来提交更改。)
您也可以在不同的线程中使用它而不会出现问题:
QSettings是可重入的。这意味着您可以同时在不同的线程中使用不同的QSettings对象。即使QSettings对象引用磁盘上的相同文件(或系统注册表中的相同条目),此保证仍然有效。如果通过一个QSettings对象修改了设置,则更改将立即在任何其他QSettings对象中可见,这些对象在同一位置上运行并且位于同一进程中。
QSettings可以安全地用于不同的进程(可以是同时运行的应用程序的不同实例或完全不同的应用程序)来读取和写入相同的系统位置。它使用建议文件锁定和智能合并算法来确保数据完整性。请注意,sync()会导入其他进程所做的更改(除了从此QSettings写入更改之外)。
答案 1 :(得分:6)
QSettings不是线程安全的。文件清楚地说明了这一点:
QSettings是可重入的。这意味着您可以使用不同的QSettings 同时在不同的线程中对象。这种保证是平等的 当QSettings对象引用磁盘上的相同文件时(或到 系统注册表中的相同条目。)
它是可重入但不是线程安全的。您无法安全地从多个线程使用全局QSettings对象。如果一个线程调用beginGroup()然后第二个线程也调用beginGroup(),那么你就会遇到问题,因为你的QSettings对象有错误的前缀。
对同一文件使用多个QSettings对象是线程安全的。因此,您应该在堆栈本地创建QSettings对象,而不是全局共享单个对象以避免竞争条件。
答案 2 :(得分:1)
我没有看到问题。
有两个基本选项:
#include <QSettings>
并知道如何访问它。如果您有自己的设置类,也是如此。接口在它自己的头文件中,并且在它自己的cpp中实现。您创建一个并将其传递给所有窗口。
class Settings
{
public:
static Settings & TheSettings()
{
static Settings theSettings_;
return theSettings_;
}
// Here go all methods for accessing the data
// You will also want:
~Settings();
Settings(const Settings &);
Settings & operator=(const Settings &);
// If you are using c++11 you may also want to add move constructor and assignment.
// Or you can just use the defaults for all the above if all your private members can destruct themselves
private:
Settings();
};
以上是QSettings作为设置对象:
class Settings
{
public:
static QSettings & TheSettings()
{
static QSettings theSettings_;
return theSettings_;
}
private:
Settings();
Settings(const Settings &);
Settings & operator=(const Settigns &);
};
希望这能让你走上正轨
PS。对于多线程应用,请确保在关键部分(或互斥保护)内访问Settings对象中的所有内部数据
PPS。请注意,Miki在评论中提到QSettings是线程安全的,因此您不必在关键部分包装对它的访问权限。但是,如果您要使用不同的底层存储(无论是文件,另一个容器),它可能是必要的。