I have a GUI I'm building with PyQt5 and it would be really convenient if I could copy and paste files directly into and from the table widget cells.
The question has already been asked a few times on this site. I tried to apply the accepted answer here as my solution.
My .ui
file imported below contains only a table widget of 10 rows and 5 columns made from qtdesigner and nothing else.
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QTableWidget, QApplication, QMainWindow, QTableWidgetItem,QFileSystemModel, QFileDialog,QVBoxLayout,QWidget
from PyQt5.QtCore import Qt
from PyQt5.uic import loadUi
import sys, csv, io
class Main_P(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
loadUi("test_copy&paste.ui",self)
self.tableWidget.installEventFilter(self)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.KeyPress and
event.matches(QtGui.QKeySequence.Copy)):
self.copySelection()
return True
return super(Main_P, self).eventFilter(source, event)
def copySelection(self):
selection = self.tableWidget.selectedIndexes()
if selection:
rows = sorted(index.row() for index in selection)
columns = sorted(index.column() for index in selection)
rowcount = rows[-1] - rows[0] + 1
colcount = columns[-1] - columns[0] + 1
table = [[''] * colcount for _ in range(rowcount)]
for index in selection:
row = index.row() - rows[0]
column = index.column() - columns[0]
table[row][column] = index.data()
stream = io.StringIO()
csv.writer(stream).writerows(table)
QtWidgets.qApp.clipboard().setText(stream.getvalue())
def keyPressEvent(self, event):
super().keyPressEvent(event)
if event.key() == Qt.Key_C and (event.modifiers() & Qt.ControlModifier):
self.copied_cells = sorted(self.tableWidget.selectedIndexes())
elif event.key() == Qt.Key_V and (event.modifiers() & Qt.ControlModifier):
r = self.tableWidget.currentRow() - self.copied_cells[0].row()
c = self.tableWidget.currentColumn() - self.copied_cells[0].column()
for cell in self.copied_cells:
self.setItem(cell.row() + r, cell.column() + c, QTableWidgetItem(cell.data()))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
win = Main_P()
win.show()
sys.exit(app.exec_())
I tried to follow the answer as best I could even though it was an answer for a Qtableview and I was using a table widget.
It doesn't work and brings up the error AttributeError: 'Main_P' object has no attribute 'copied_cells'
whenever I press ctr+V
How do I go about fixing this?