Qt:避免在字符串更改的情况下重建应用程序
Qt : Avoid Rebuilding Applications incase strings change
我想知道在QT应用程序中存储字符串的选项是什么。 我的主要要求之一是不要重新构建整个项目或任何文件,以防一个字符串更改并将所有字符串放在一个地方。简而言之,我想将字符串放在一个地方并在应用程序启动期间提取它们
我已经使用了上面答案中讨论的所有元素。
XML
,JSON
,QSettings
带 Ini 文件,tr()
他们都可以很好地做到这一点。 我整理了一些关于不同选项的注释:
QTranslator
Qt Linguist和tr()
标签旨在获取您的库存语言并将其翻译成另一种语言。 在没有Qt Linguist的情况下跟踪英语翻译的多个版本并进行修改/发布几乎是不可能的。 Qt Linguist需要"发布"您的翻译,并将其从TS文件(翻译源)转换为优化的QM文件。
QM 文件格式是本地化应用程序使用的紧凑二进制格式。它为翻译提供了极快的查找。
以下是使用翻译文件的样子:
QTranslator translator;
translator.load("hellotr_la");
app.installTranslator(&translator);
http://qt-project.org/doc/qt-4.8/qtranslator.html#details
我认为使用QTranslator
进行一些字符串更改可能是一个奇怪的用例,除非您用于本地化程序。 但就像文档所说的那样,它针对非常快速的字符串替换查找进行了优化。
QXMLStreamReader
流读取器是访问XML文件的"推荐"方式,或者至少具有更好的支持。 您可以编写自己的文件来组织它,或者编写代码来生成 XML。
<STRING_1>Some string</STRING_1>
以下是导航到 xml 的外观。
QXmlStreamReader xml;
...
while (!xml.atEnd()) {
xml.readNext();
... // do processing
}
if (xml.hasError()) {
... // do error handling
}
XML 与 JSON 非常相似,但文件较大,开始和结束标记更长。 XML的库存阅读器要多得多。 在许多情况下,它也更具人类可读性,因为很多人都知道html并且它们非常相似。
QJson文档
Qt 5中的JSON支持看起来非常好。我还没有用它构建一个项目它看起来很简单,就访问和设置而言,它看起来就像使用字典、地图或矢量一样。
更新:您只需将指针传递到QJsonDocument
、QJsonObject
或QJsonArray
中,因为您可以更深入地导航或将更多内容附加到Json
文件中。 完成后,您可以将其保存为二进制文件,或明文,人类可读的文件,并具有适当的缩进和所有内容!
如何在Qt5中创建/读/写JSon文件
Json似乎正在成为许多人XML的替代品。 我喜欢使用 Json 保存和加载角色扮演游戏状态的示例。
http://qt-project.org/doc/qt-5/qtcore-savegame-example.html
Q沉淀
QSettings是我的最爱之一,只是因为它已经支持了很长时间,并且这是大多数持久设置应该保存和访问的方式。
当我使用它时,为了利用默认值和回退机制,我把它放在我的 main.cpp:
QCoreApplication::setOrganizationName("MySoft");
QCoreApplication::setOrganizationDomain("mysoft.com");
QCoreApplication::setApplicationName("Star Runner");
因为我有时发现需要在窗口中手动编辑这些设置,所以我使用 Ini 格式。
QSettings::setDefaultFormat(QSettings::IniFormat); // also in main.cpp
然后,当我部署我的 exe 并且我想加载特定值而不是硬编码默认值时,安装程序会将主回退放入
C:/ProgramData/MySoft/Star Runner.ini
当程序在运行时保存更改时,它会保存到:
C:/Users/<username>/AppData/Roaming/MySoft/Star Runner.ini
然后在整个程序中,如果我需要获取设置或设置设置,则需要 3 行或更少的代码。
// setting the value
QSettings s;
s.setValue("Strings/string_1", "new string");
// getting the value
QString str;
QSettings s;
str = s.value("Strings/string_1", "default string").toString();
这是您的ini文件的外观:
[Strings]
string_1=default string
如果要存储一些要在部署或运行时更改的字符串,则QSettings
是要走的路。 (或者如果现在选中了复选框,或者您的窗口大小和位置,或者最近的文件列表或其他任何内容)。
QSettings
已经进行了相当多的优化,并且经过深思熟虑。 ini 支持很棒,除了它有时会对组和键(通常按字母顺序)重新排序,并且可能会删除您在其中输入的任何注释。 我认为 ini 评论要么以;
开头,要么以#
开头.
希望有帮助。
一种方法是将其放在共享库中。这样,您只能重新编译共享库,而不能重新编译整个项目。另一种方法是将其放在文件或数据库中,并在运行时加载它。
当然,您必须检查包含依赖项。如果您在所有位置都包含标头,编译器将重建依赖于它的所有内容,即使实际上并不需要标头也是如此。
另一种可能的解决方案是将所有字符串替换为调用tr()
中的默认字符串,并使用Qt Linguist管理所有字符串。
您还可以在启动时从外部.qm
文件加载所有"翻译"。
很简单:将易失性字符串存储在QSettings http://qt-project.org/doc/qt-4.8/qsettings.html(您可以使用ini文件或注册表)或XML文件中,这将使您的应用程序可配置。
编辑:好吧,再考虑几分钟后,Guilherme的评论是正确的。QSettings 需要以某种方式初始化(手动或从代码中的某些默认值)...老实说,手动编辑注册表以更改几个字符串并不是最聪明的主意。所以我的结论是XML或JSON肯定更好。它具有优点,例如,您可以保留多个配置文件,允许您在运行时切换语言等。
- 在没有太多条件句的情况下,我如何避免被零除
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 在未初始化映射的情况下,将值插入到映射的映射中
- 是默认情况下分配给char数组常量的值
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 如何在不产生任何垃圾的情况下获得C中的像素
- 在已经使用Git的情况下减少编译时间
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 如何在没有信号的情况下从C++执行QML插槽
- 如何在不知道向量大小的情况下输入向量内部的向量?
- 为什么在某些情况下不写入此文件?
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 在没有Xcode的情况下在Mac捆绑包中嵌入框架
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- Eclipse CDT:如何在没有项目清理>>项目重建的情况下重新链接静态库
- Qt:避免在字符串更改的情况下重建应用程序
- 如何在<int>不重建数组的情况下将 vector<vector> 转换为 int**?
- 有没有一种方法可以在不重建任何项目的情况下重新链接解决方案
- 在没有关于相机的信息的情况下从2个图像进行三维重建
- 在不停止调试的情况下重建项目