我需要在 QtableWidget 中拖放(移动)CellWidget。
我可以移动它们,但如果我将一个 CellWidget 放在另一个 CellWidget 占据的单元格上,我就会删除前一个。
示例:(行、列)
B(0, 1) 移动到 (1, 2)
C(0, 2) 移动到 (0, 1)
B 已删除。
更多:cellWidget 不能放在旧位置。
这是我的最小代码。
from PySide6.QtWidgets import QApplication, QHBoxLayout, QWidget, QPushButton, QTableWidget
from PySide6.QtCore import Qt, QMimeData
from PySide6.QtGui import QDrag
class DragButton(QPushButton):
def mouseMoveEvent(self, e):
if e.buttons() == Qt.LeftButton:
drag = QDrag(self)
mime = QMimeData()
drag.setMimeData(mime)
drag.exec(Qt.MoveAction)
class Window(QWidget):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
self.nb_col = 5
self.nb_row = 5
self.tbl = QTableWidget(self.nb_row, self.nb_col)
self.tbl.setHorizontalHeaderLabels([str(x) for x in range(self.nb_col)])
self.tbl.setVerticalHeaderLabels([str(x) for x in range(self.nb_row)])
self.layout = QHBoxLayout()
self.layout.addWidget(self.tbl)
nom = ['A', 'B', 'C', 'D']
for l in range(len(nom)):
new_btn = DragButton(nom[l])
new_btn2 = DragButton(nom[l] + 'j')
self.tbl.setCellWidget(0, l, new_btn)
self.tbl.setCellWidget(l, 1, new_btn2)
self.setLayout(self.layout)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
position = e.position()
widget = e.source()
row = self.tbl.rowAt(position.y() - self.tbl.horizontalHeader().height() - self.tbl.y())
column = self.tbl.columnAt(position.x() - self.tbl.x())
self.tbl.setCellWidget(row, column, widget)
e.accept()
if __name__ == "__main__":
app = QApplication([])
w = Window()
w.showMaximized()
app.exec()
感谢您的帮助。 克里斯托夫
我可能来晚了一点^^但我在 QTableWidget 上遇到了同样的问题,技巧是创建一个临时的 QWidget 和 QHBoxLayout 在其中放置按钮或其他东西。这样,那些临时小部件就会被销毁。
from PySide6.QtWidgets import QApplication, QHBoxLayout, QWidget, QPushButton, QTableWidget
from PySide6.QtCore import Qt, QMimeData
from PySide6.QtGui import QDrag
class DragButton(QPushButton):
def mouseMoveEvent(self, e):
if e.buttons() == Qt.LeftButton:
drag = QDrag(self)
mime = QMimeData()
drag.setMimeData(mime)
drag.exec(Qt.MoveAction)
class Window(QWidget):
def __init__(self):
super().__init__()
self.setAcceptDrops(True)
self.nb_col = 5
self.nb_row = 5
self.tbl = QTableWidget(self.nb_row, self.nb_col)
self.tbl.setHorizontalHeaderLabels([str(x) for x in range(self.nb_col)])
self.tbl.setVerticalHeaderLabels([str(x) for x in range(self.nb_row)])
self.layout = QHBoxLayout()
self.layout.addWidget(self.tbl)
nom = ['A', 'B', 'C', 'D']
for l in range(len(nom)):
new_btn = DragButton(nom[l])
new_btn2 = DragButton(nom[l] + 'j')
self.set_cell_widget(0, l, new_btn)
self.set_cell_widget(l, 1, new_btn2)
self.setLayout(self.layout)
def set_cell_widget(self, row, column, widget):
container_widget = QWidget()
container_layout = QHBoxLayout()
container_layout.setContentsMargins(0, 0, 0, 0)
container_layout.setSpacing(0)
container_widget.setLayout(container_layout)
container_layout.addWidget(widget)
self.tbl.setCellWidget(row, column, container_widget)
def dragEnterEvent(self, e):
e.accept()
def dropEvent(self, e):
position = e.position()
widget = e.source()
row = self.tbl.rowAt(position.y() - self.tbl.horizontalHeader().height() - self.tbl.y())
column = self.tbl.columnAt(position.x() - self.tbl.x())
self.set_cell_widget(row, column, widget)
e.accept()
if __name__ == "__main__":
app = QApplication([])
w = Window()
w.showMaximized()
app.exec()
希望这有帮助!