QStyle所有权

4
当在Qt应用程序中使用样式时,我遇到了一个有趣的问题,即QStyle所有权。QStyle继承自QObject,通常接受QObject* parent作为构造函数参数来管理其子对象的生命周期。但是,QStyle的构造函数没有这个构造函数参数。第一个问题 - 为什么?
此外,当使用QApplication::setStyle(QStyle * style)设置整个应用程序的样式时,文档说应用程序对象会获取样式的所有权。因此,编写(如文档中所示)app->setStyle(new MyWonderStyle())应该是安全的,并且应用程序在不再使用样式时应该删除样式。我希望它确实这样做。
但是,在QWidget::setStyle(QStyle* style)中,文档说明没有转移所有权。因此,在我的看法中,如果小部件的样式设置超过一次或小部件被删除,则编写widget->setStyle(new MyWonderStyle())会导致内存泄漏。
所以我的问题是 - 在Qt中管理自定义样式的最佳实践特别是所有权方面是什么?是否有某种标准方式,还是完全由开发人员处理?

文档还说最好的做法是使用QApplication::setStyle。为什么要专门为单个QWidget设置样式并多次更改它呢? - JefGli
@ Jeffrey:我遇到了一段非常大的旧代码,并发现像widget->setStyle(new MyStyle())这样的内存泄漏。应用程序可能不会多次设置小部件的样式(但通常可能会),但是小部件肯定会在程序结束之前被销毁,留下创建的样式作为孤儿。因此,我很好奇如何在不完全重新设计代码的情况下解决这个问题。 - HiFile.app - best file manager
如果是这种情况,我只需要将MyStyle()更改为MyStyle(widget),然后就完成了。这不是最干净的解决方案,但它可以解决您的内存泄漏问题。 - JefGli
但我的样式是通过QProxyStyleQStyle继承的,这些类没有以带有parent参数的构造函数,正如我上面所写的。我相信我可以在我的类中创建这样的构造函数,然后我可以在构造函数体中调用setParent(widget),但是...我想QStyle为什么不在构造函数中使用parent,这一点我还不理解。 - HiFile.app - best file manager
确实,你是对的。抱歉我没有做足研究。查看QStyle源代码也没有给我太多答案。 - JefGli
1个回答

6
我认为 QApplication::setStyle(QStyle*) 接受 QStyle 的所有权,因为有一个重载函数 QApplication::setStyle(QString)。这个函数在程序内部创建了一个 QStyle 对象并接受了它的所有权,因为在那种情况下没有其他选择。在一个函数中接受所有权,在另一个函数中不接受所有权可能会导致混淆。
另一方面,QWidget 不接受 QStyle 的所有权,因为您可能希望将相同的样式分配给多个 QWidget
缺少 QStyle(QObject*) 构造函数可能只是疏忽。您可以安全地使用 setParent(QObject*) 代替。事实上,QApplication::setStyle(QStyle*) 使用 setParent 接受 QStyle 的所有权。

我同意。传统应用程序应该设置样式的所有权,而派生样式构造函数应该采用QObject * parent = Q_NULLPTR,即使QStyle构造函数没有这样做! - Kuba hasn't forgotten Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接