【问题标题】:PyQt5 Move a QTableWidget from a cell into another onePyQt5 将 QTableWidget 从一个单元格移动到另一个单元格
【发布时间】:2017-07-17 17:21:30
【问题描述】:

我在 PyQt5 应用程序中有一个 6x1(6 行,1 列)QTableWidget 表。

当程序启动时,所有表格的单元格都被一个灰色背景的 QTableWidgetItem 填充

self.shaftsTable = QtWidgets.QTableWidget()
# table setups (...)

for i in range(self.nf):
    for j in range(self.nc):
        item = QtWidgets.QTableWidgetItem()
        item.setBackground(QtGui.QColor(200,200,200))
        self.shaftsTable.setItem(i, j, item)

然后一个QtWidgets.QListWidget被放置在最下面的单元格(第5行,第0列)

el = QtWidgets.QListWidget(Window)
self.shaftsTable.setCellWidget(5, 0, el)

假设该表将模拟穿过 6 层楼的电梯路径:电梯是一个 QtWidgets.QListWidget,其中包含当前在电梯中的所有乘客的列表;电梯从最低层开始,因此它被放置在桌子的位置(5,0)。

我想将电梯从单元格(5,0)移动到单元格(4,0),即从最低楼层移动到下一层后,电梯只会在单元格(4,0)中,并且不在单元格 (5,0) 中。

以下内容不起作用,因为 removeCellWidget() 也会从单元格 (4,0) 中明确删除对象:

el = self.shaftsTable.cellWidget(5, 0)
self.shaftsTable.setCellWidget(4, 0, el)
self.shaftsTable.removeCellWidget(5, 0)

我在 PyQt 文档 http://pyqt.sourceforge.net/Docs/PyQt4/qtablewidget.html 中没有找到任何简单的函数来做我需要的事情

我尝试制作电梯的副本(使用 copy.deepcopy()),将副本放在单元格 (4,0) 中,然后删除单元格 (5,0) 中的原始电梯,但 copy.deepcopy() 失败在 QtWidgets.QListWidget 上。

您有什么想法或建议吗? (我确信有一种或多种方法可以解决我的问题,但作为新手,我想不出一个)

【问题讨论】:

    标签: python qt pyqt pyqt5


    【解决方案1】:

    此处引用https://forum.qt.io/topic/61590/take-a-widget-from-a-qtablewidget

    从 QTableWidget 中获取一个小部件

    当您使用 setCellWidget 时,QTableWidget 将拥有该小部件。 阅读文档,似乎没有办法收回所有权 cellWidget() 只允许访问它而不是收回它。

    因此,一种方法是创建可以根据需要创建小部件的函数,并且 当您想“交换”它们时,只需重新创建小部件 你不能真正复制。

    所以你可以创建一个函数来获取小部件并复制一些数据 从中创建一个新的数据 如果未提供小部件,则使用默认值创建一个新的。


    因此,没有办法从 QTableWidget 的单元格中获取 QTableWidget 的所有权,以便将其移动到另一个单元格。

    唯一的解决方案是复制您要移动的 QTableWidget,将副本放入目标单元格(在我的情况下为单元格 (4,0)),然后从原始单元格中删除原始 QTableWidget 对象(在我的案例单元格 (5,0))。

    new_el = QtWidgets.QListWidget(Window)
    el = self.shaftsTable.cellWidget(5, 0)
    
    # copy contents of el into new_el with a custom function:
    def unloadAllPassengers(el):
        unloaded = []
        for _ in range(el.count()):
            unloaded.append(el.takeItem(0))
        return unloaded
    
    def loadPassengersAsQListWidgetItemArray(el, qListWidgetItemArray):
        for i in range(len(qListWidgetItemArray)):
            el.addItem(qListWidgetItemArray[i])
    
    loadPassengersAsQListWidgetItemArray(new_el, unloadAllPassengers(el))
    
    self.shaftsTable.setCellWidget(5, 0, None)
    self.shaftsTable.setCellWidget(4, 0, new_el)
    # an elevator is in cell (4,0) whlist "el" does not exists anymore
    # problem solved
    

    【讨论】: