0

我的问题是一个简单但令人讨厌的用户体验破坏了一个。我正在尝试QGraphicsItemQGraphicsScene. 我还需要 a QGraphicsLayout,但据我了解,不能简单地将布局放在场景上,因为必须在 a 上设置布局QGraphicsWidget,然后将小部件添加到场景中。

现在,当我需要加载大量项目并准备将它们显示时,场景只是空置在那里,因为我无法使上述QGraphicsWidget. 只有最后才能将其添加到场景中,否则将不会显示任何以后的更改。

目标:向场景添加某种布局管理 -> {准备一个项目 -> 将项目添加到布局 -> 显示 -> 准备一个项目 ->} 重复...

但是我有:{准备一个项目->准备另一个项目->}重复...->将所有内容添加到布局->在场景中设置布局管理->显示

那么问题来了:有什么方法可以为场景创建响应式布局/容器,在添加新子对象后重新绘制自身?

4

2 回答 2

0

设法找到我的错误。它位于我为QGraphicsWidget.

正如文档在设置布局时所说:

当前由布局或其所有子布局管理的所有小部件将自动重新设置为该项目的父级。然后布局无效,并且子部件的几何形状根据此项的geometry() 和contentsMargins() 进行调整。未明确由布局管理的子级在分配给此小部件后不受布局影响。

在将布局设置为小部件后,添加到其中的任何新项目都不会重新设置为小部件,因此它们保持不受影响且不显示。

在插入到布局的每个项目上调用QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem* newItem) 链接解决了我的问题。

于 2017-02-02T23:48:46.917 回答
0

来自 Qt 手册:

当场景改变时,(例如,当一个项目移动或变形时)QGraphicsScene 发出 changed() 信号。

它没有提到 addItem() 和 removeItem()。希望这些也包括在内。

如果是这样,您可以应用以下内容:

信号处理程序可以“捕捉”变化并请求场景的重绘(例如通过invalidate())。(Un-)幸运的是,这不会立即重绘场景(使用其父视图),但会排队重绘事件。因此,在事件循环再次通过之前,不会完成实际的重绘。

(事件循环是 QApplication 的一部分。如果您在用户界面启动的命令内停止应用程序,您将在调用堆栈中找到如下内容:

Qt5Cored.dll!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags)
Qt5Cored.dll!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags)
Qt5Cored.dll!QCoreApplication::exec()

)

您可以通过调用 QApplication::processEvents() 来强制执行此操作。(它甚至是静态的。)AFAIK,如果嵌套事件循环通常没有问题,因为它们为此做好了准备(只要没有形成非终止递归)。

但是,这可能需要一些微调,因为过多的重绘可能会大大降低您的应用程序的速度。

于 2017-02-02T11:56:04.120 回答