在运行时删除/修改静态 Qt 资源

Posted

技术标签:

【中文标题】在运行时删除/修改静态 Qt 资源【英文标题】:Removing/modifying static Qt resources in run-time 【发布时间】:2017-09-26 13:29:23 【问题描述】:

作为 Qt Designer hacking 的一部分,我有兴趣在运行时删除资源(特别是 :/trolltech/widgetbox/widgetbox.xml)。有关上下文的更多详细信息,请参阅文章末尾。

我明显的(并且失败的)尝试是:

QFile(":/trolltech/widgetbox/widgetbox.xml").remove();

但它返回了一个错误。

我的下一个尝试是使用Q_CLEANUP_RESOURCE(widgetbox),但它所扩展的功能只能在 Qt Designer 的私有组件 (QDesignerComponents) 中使用。

另一个尝试是清除文件的内容,但它是只读的:

QFile f(":/trolltech/widgetbox/widgetbox.xml");
if (f.open(QFile::WriteOnly))  ...  // returns false

我还尝试通过定义我自己的:/trolltech/widgetbox/widgetbox.xml 在 Qt 资源的文件系统中覆盖它。我可以打开文件,但无法检索数据,我猜是因为它是重复资源(将资源别名为未使用的名称会使应用程序正确打印出内容)。另一方面,小部件列表显示正确。

QFile f(":/trolltech/widgetbox/widgetbox.xml");
if (f.open(QFile::ReadOnly)) 
    qDebug() << "";
    qDebug() << f.readAll(); // shows nothing
    qDebug() << "";

有没有办法在运行时修改/删除/替换资源文件?


如果您认为这是XY problem,我将解释整个上下文:我正在通过对独立的IDE 进行小的调整将Qt Designer 集成到我自己的IDE 中。基本上,我添加了一个编译标志来生成动态库而不是可执行文件,并添加了一些选项来公开主窗口。

在此 IDE 中,我想添加一个选项以避免用户使用默认小部件并将列表限制为一组自定义小部件。我提到的资源是包含 Qt Designer 中默认可用的小部件列表的文件。可以通过插件轻松包含其他小部件,但我还没有找到删除默认小部件的方法。

我有一个选择是使该负载成为可选的,但它会在许多项目中产生一连串的变化。我想避免过多地修改 Qt Designer。

【问题讨论】:

【参考方案1】:

您已经在使用 Qt Designer,所以首先您应该将它包含在您的构建中,其次您将可以访问它的所有类 - 不再是“私有”组件之类的东西,它是 您的 现在编码。让它为你工作!

Qt 资源可以在单独的二进制文件中编译或生成。您可以将此资源放入单独的二进制文件中,然后通过registerResource/unregisterResource 轻松加载和卸载它。

QFile 使用基于QAbstractFileEngine 的虚拟文件系统。 QAbstractFileEngineHandler::create 的实现充当过滤器,可以捕获请求并让您的文件引擎在需要时处理它。例如。您的文件引擎可能会在打开时失败 - 这相当于删除资源。

请注意,自从 Qt 5 以来,QAbstractFileEngine 不再是公开的,大概 Qt 人正在考虑用其他东西替换它。要使用这些 API,您需要将 qt += core-private 添加到项目的 qmake 文件中。

【讨论】:

谢谢@kuba-ober!我去看看文件引擎和registerResource,这需要我一段时间来测试,但我会告诉你的! 顺便说一句,关于修改,客户希望能够迁移到 Qt 的未来版本,所以我想减少完成的工作量为了尽快赶上新版本的 Qt。 您可以设置一个私有 git 源存储库来跟踪 qt 基础存储库的设计器文件夹。使用sparse checkout 和浅拉来仅拉取所需的代码。然后将您的更改添加到存储库。当需要升级到更新的 Qt 版本时,请重新设置您的分支。您可能会遇到一些冲突,但这些冲突只会出现在 Qt 代码和您的代码更改重叠的地方。您可以将该项目作为子模块添加到项目的 git 存储库中。没有 git = SOL。 registerResource 的建议很有帮助,谢谢!

以上是关于在运行时删除/修改静态 Qt 资源的主要内容,如果未能解决你的问题,请参考以下文章

使用静态 Qt 应用程序时如何更改 Qt 字体的路径?

在运行时从静态 UITableView 中删除行

静态链接到 Qt 时加载 Qt 插件?

35.QT-多线程

c++ 在运行时修改资源

QT交叉编译时怎么添加静态库,急!!!