在运行时将 Qt 小部件拖放到网格中

Drag and dropping Qt widgets in a grid at runtime

这是我正在尝试做的事情:我有一些通过自定义小部件显示的数据。这样的数据很多。在运行时,用户将看到所有数据的列表,他们将选择他们想要监控的数据,这将在网格中动态创建自定义小部件。我想让用户随心所欲地重新组织网格中的小部件,最好是通过拖放。

我能找到的最接近实现此目的的方法是使用具有以下属性的 QTableWidget:setDragEnabled(True)、setDragDropOverwriteMode(False)、setDragDropMode(QtGui.QAbstractItemView.InternalMove)。使用这些属性,可以拖动单元格并将它们移动到其他单元格。

但是,这似乎只适用于附加到每个单元格的 QTableWidgetItem,不适用于通过 setCellWidget() 设置的小部件。

这是一个小项目,说明了我正在尝试做的事情:https://gist.github.com/anonymous/02bbcc201316fa8f43e9

您可以看到创建的小部件(通过单击按钮)不可拖放,但是如果您编辑单元格(设置 QTableWidgetItem),则这些小部件可拖放。看起来单元格的cellWidget部分和item部分是完全独立的,拖放逻辑只适用于items,不适用于cell widgets

恐怕我已经知道答案了,但是...除了用 QTableView 替换 QTableWidget、使用模型并重新实现所有拖放操作之外,还有什么方法可以做我想做的事吗?我自己放弃逻辑?

或者我的做法完全错误。也许我可以使用其他一些小部件或 Qt 工具?我愿意接受任何和所有的建议。

提前致谢!

我不确定有人回答他们自己的问题是否合适,但我解决了我的问题,我想我会提供我的解决方案。也许将来会对某人有所帮助。

这是我所做的:

首先,我编写了一个从 QTableWidget 派生的 GridWidget,使用自定义的 dropEvent() 方法来处理周围移动的小部件。

由于 QAbstractListView 管理附加到索引的小部件列表的方式,无法移动现有小部件,因为原始单元格中的小部件将被销毁。所以我写了一个 ContainerWidget,它只是另一个小部件的布局。 ContainerWidget class 有一个 cloneAndPassContainedWidget() 方法可以完成您所期望的:它 returns 一个新的 ContainerWidget 并赋予它所包含的小部件的所有权。很明显调用方法后,原来的ContainerWidget就没用了,但是这个方法被调用(并且存在)正是因为widget被设置为销毁,所以这不是问题。

这是一个简单的项目,展示了我在实践中的解决方案:https://gist.github.com/anonymous/a3b2d7e61c6b3e11742c

我相当确定正确的方法是编写模型、视图和委托,但在我的情况下,这需要太多的工作,所以这个解决方案是一个可以接受的解决方法。