如何将文件放入 PyQt5 中的 QTableWidget

How to drop a file into a QTableWidget in PyQt5

我正在尝试创建一个 table-widget,我可以在其中放置音频文件并使用文件名、文件大小等填充 table。我的代码如下。我还没有实现用于读取 dragEnterEvent 上的元数据的部分,因为 table 甚至不接受任何类型的掉落。

from PyQt5 import QtCore, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(982, 615)
        MainWindow.setAcceptDrops(True)
        MainWindow.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.label = QtWidgets.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(360, 0, 271, 181))
        self.label.setText("")
        self.label.setObjectName("label")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(10, 200, 701, 331))
        self.tableWidget.setAcceptDrops(True)
        self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget.setDragDropMode(QtWidgets.QAbstractItemView.DragDrop)
        self.tableWidget.setDefaultDropAction(QtCore.Qt.CopyAction)
        self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget.setShowGrid(False)
        self.tableWidget.setSortingEnabled(True)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.horizontalHeader().setVisible(True)
        self.tableWidget.verticalHeader().setVisible(False)
        self.tableWidget.setRowCount(6)
        self.tableWidget.setColumnCount(6)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 982, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.titleUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def dragEnterEvent(self, event):
        event.accept()

    def dropEvent(self, event):
        event.accept()

    def titleUi(self, MainWindow):
        MainWindow.setWindowTitle("tableWidget")



if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

如何让 table 接受掉落?

首先,您应该导入 pyuic 创建的文件,而不是直接编辑它,否则如果您在 Qt Designer 中进行进一步的更改,您的所有编辑都将丢失。 (下面的示例代码将展示如何做到这一点)。

其次,您需要确保 table 接受丢弃,并指定它可以接收的数据类型。有了它,您就可以监听放置事件并将任何放置的文件添加到 table.

在使用下面的示例之前,您应该重新运行 pyuic。该示例假定 ui 模块将在同一目录中另存为 mainwindow.py。如果您想使用不同的名称,则需要相应地编辑导入行。

import sys
from PyQt5 import QtCore, QtWidgets
from mainwindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowTitle('TableWidget')
        self.tableWidget.setAcceptDrops(True)
        self.tableWidget.viewport().installEventFilter(self)
        types = ['text/uri-list']
        types.extend(self.tableWidget.mimeTypes())
        self.tableWidget.mimeTypes = lambda: types
        self.tableWidget.setRowCount(0)

    def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.Drop and
            event.mimeData().hasUrls()):
            for url in event.mimeData().urls():
                self.addFile(url.toLocalFile())
            return True
        return super().eventFilter(source, event)

    def addFile(self, filepath):
        row = self.tableWidget.rowCount()
        self.tableWidget.insertRow(row)
        item = QtWidgets.QTableWidgetItem(filepath)
        self.tableWidget.setItem(row, 0, item)
        self.tableWidget.resizeColumnToContents(0)

if __name__ == '__main__':

    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())