将项目从 QListWidget 拖放到 pyQT 中的 QTableWidget

问题描述 投票:0回答:1

我的主窗口中有一个 QListWidget 和一个 QTableWidget。我需要从 QListWidget 中拖动一个元素并将其作为行或列放置在 QTableWidget 中(取决于事件是从垂直还是水平标题触发)。

但我无法在标题上自定义 dropEvent:将项目“Item 1”拖到表中第 2 行和第 3 行之间应该添加名为“Item 1”的新行。

Screenshot of the attempted action

我尝试在 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_())
python pyqt5 drag-and-drop qtablewidget qlistwidget
1个回答
0
投票

看起来我已经开始弄清楚如何做我需要做的事情了。 将以下几行添加到“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)
© www.soinside.com 2019 - 2024. All rights reserved.