我的主窗口中有一个 QListWidget 和一个 QTableWidget。我需要从 QListWidget 中拖动一个元素并将其作为行或列放置在 QTableWidget 中(取决于事件是从垂直还是水平标题触发)。
但我无法在标题上自定义 dropEvent:将项目“Item 1”拖到表中第 2 行和第 3 行之间应该添加名为“Item 1”的新行。
我尝试在 QTableWidget 中自定义事件,但它仅适用于单元格:
class customTable(QTableWidget):
def __init__(self, parent):
super().__init__(parent)
# Set Style
self.setStyleSheet(tableStyle)
# ScrollBars
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
# Allow to drop elements
# self.setDragEnabled(True)
# self.setDragDropOverwriteMode(True)
# self.setDragDropMode(QAbstractItemView.DragDrop)
# self.setDefaultDropAction(Qt.MoveAction)
# Allow to replace rows and columns in the table
self.verticalHeader().setSectionsMovable(True)
self.horizontalHeader().setSectionsMovable(True)
# verticalHeader Drop
self.verticalHeader().setDragEnabled(True)
self.verticalHeader().setDragDropOverwriteMode(True)
self.verticalHeader().setDragDropMode(QAbstractItemView.DropOnly)
# horizontalHeader Drop
self.horizontalHeader().setDragEnabled(True)
self.horizontalHeader().setDragDropOverwriteMode(True)
self.horizontalHeader().setDragDropMode(QAbstractItemView.DropOnly)
def dropEvent(self, event):
if event.mimeData().hasFormat('application/x-qabstractitemmodeldatalist'):
data = event.mimeData()
source_item = QStandardItemModel()
source_item.dropMimeData(data, Qt.CopyAction, 0,0, QModelIndex())
print(source_item.item(0, 0).text())
关于如何获得这种期望的行为有什么建议吗?
没有自定义表格的代码:
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableWidget, QTableWidgetItem, QAbstractItemView, QHBoxLayout, QWidget, QListWidget
from PyQt5.QtCore import Qt
tableStyle = '''
QTableWidget::item {background-color: "#F4FAFB";
border-style: outset;
border-width:1px; border-radius: 2px; border-color: #AEAEAE}
QTableWidget::item:selected {background-color: #66C3D0;
border-width:1px; border-radius: 2px; color: white; border-color: #333333}
'''
class TableDemo(QMainWindow):
def __init__(self):
super().__init__()
# Create a ListWidget
self.list = QListWidget(self)
self.list.addItem('Item 1')
self.list.addItem('Item 3')
self.list.addItem('Item 4')
# Set Drag and Drop
self.list.setDragDropMode(QAbstractItemView.DragOnly)
# Create a QTableWidget
self.table = QTableWidget(self)
# # Set Style
self.table.setStyleSheet(tableStyle)
# Set number of rows and columns
self.table.setRowCount(5)
self.table.setColumnCount(3)
# Set headers
self.table.setHorizontalHeaderLabels(['Column 1', 'Column 2', 'Column 3'])
self.table.setVerticalHeaderLabels(['Row 1', 'Row 2', 'Row 3', 'Row 4', 'Row 5'])
# ScrollBars
self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
# Allow to replace rows and columns in the table
self.table.verticalHeader().setSectionsMovable(True)
self.table.horizontalHeader().setSectionsMovable(True)
# Customize Drop Event
self.table.verticalHeader().setDragEnabled(True)
# self.table.verticalHeader().setDragDropOverwriteMode(True)
self.table.verticalHeader().setDragDropMode(QAbstractItemView.DropOnly)
self.table.horizontalHeader().setDragEnabled(True)
# self.table.horizontalHeader().setDragDropOverwriteMode(True)
self.table.horizontalHeader().setDragDropMode(QAbstractItemView.DropOnly)
# Populate the table with data
for row in range(5):
for col in range(3):
self.table.setItem(row, col, QTableWidgetItem(f"Item ({row+1}, {col+1})"))
# self.table.item(row,col).setText('New text')
# self.table.item(row, col).setFlags(Qt.ItemFlag.ItemIsDragEnabled | Qt.ItemFlag.ItemIsDropEnabled)
# Layout setup
layout = QHBoxLayout()
layout.addWidget(self.list)
layout.addWidget(self.table)
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
# Window properties
self.setWindowTitle("QTableWidget Demo")
self.resize(800, 300)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = TableDemo()
window.show()
sys.exit(app.exec_())
看起来我已经开始弄清楚如何做我需要做的事情了。 将以下几行添加到“customTable”类中:
# Custom headers
HH = customQHeaderView(parent = self, orientation=Qt.Horizontal)
VH = customQHeaderView(parent = self, orientation=Qt.Vertical)
self.setHorizontalHeader(HH)
self.setVerticalHeader(VH)
并添加了新类“customQHeaderView”:
class customQHeaderView(QHeaderView):
MimeType = 'application/x-qabstractitemmodeldatalist'
def __init__(self, orientation: Qt.Orientation, parent=None):
super().__init__(orientation, parent)
self.setDragEnabled(True)
self.setAcceptDrops(True)
def dropEvent(self, event):
mimedata = event.mimeData()
if mimedata.hasFormat(customQHeaderView.MimeType):
if event.source() is not self:
source_item = QStandardItemModel()
source_item.dropMimeData(mimedata, Qt.CopyAction, 0,0, QModelIndex())
label = source_item.item(0, 0).text()
print(label)
event.setDropAction(Qt.MoveAction)
event.accept()
else:
event.ignore()
else:
super().dropEvent(event)