简体   繁体   中英

PyQt5: copy/paste from a QTableWidget, with ContextMenu and with KeyboardPress

I am trying to copy the data in my QTableWidget to other spreadsheets, and paste other data if necessary, with two possibilities, a right click on the mouse and clicking the copy Action or using the keyboard "ctrl+c".

I found an answer before and I did write the code provided on that answer, but I think I missed it, can someone please tell me what I did wrong, here is the answe r that I found. when I copy the data from the QTableWidget and paste it, the following sentence is pasted: self.results_table_Specific.installEventFilter(self), not the selected data here is my code:

class Calculation_window_Specific(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("specific_calculation_window.ui",self)
        self.setStyleSheet(stylesheet2)
        self.setWindowTitle('specific calculation table')
        self.setWindowIcon(QtGui.QIcon("logo.ico"))
        self.actionExcel_xlsx.triggered.connect(self.Export_to_Excel2)
        self.results_table_Specific.installEventFilter(self)  

        self.clipboard = []           
    def eventFilter(self,source,event):
        if event.type()== QtCore.QEvent.KeyPress:
            if event==QtGui.QKeySequence.Copy:
                self.copySelection()
                return True
            elif event==QtGui.QKeySequence.Paste:
                self.pasteSelection()
                return True
        elif event.type() == QtCore.QEvent.ContextMenu:
            # a context menu for the copy/paste operations
            menu = QtWidgets.QMenu()
            copyAction = menu.addAction('Copy')
            copyAction.triggered.connect(self.copySelection)
            pasteAction = menu.addAction('Paste')
            pasteAction.triggered.connect(self.pasteSelection)
            if not self.results_table_Specific.selectedIndexes():
                # no selection available, both copy and paste are disabled
                copyAction.setEnabled(False)
                pasteAction.setEnabled(False)
            if not self.clipboard:
                # no clipboard contents, paste is disabled
                pasteAction.setEnabled(False)
            menu.exec(event.globalPos())
            return True
        return super(Calculation_window_Specific, self).eventFilter(source, event)
    
    def copySelection(self):
        # clear the current contents of the clipboard
        self.clipboard.clear()
        selected = self.results_table_Specific.selectedIndexes()
        rows = []
        columns = []
        # cycle all selected items to get the minimum row and column, so that the
        # reference will always be [0, 0]
        for index in selected:
            rows.append(index.row())
            columns.append(index.column())
        minRow = min(rows)
        minCol = min(columns)
        for index in selected:
            # append the data of each selected index
            self.clipboard.append((index.row() - minRow, index.column() - minCol, index.data()))

    def pasteSelection(self):
        if not self.clipboard:
            return
        current = self.results_table_Specific.currentIndex()
        if not current.isValid():
            # in the rare case that there is no current index, use the first row
            # and column as target
            current = self.model.index(0, 0)

        firstRow = current.row()
        firstColumn = current.column()

        # optional: get the selection model so that pasted indexes will be
        # automatically selected at the end
        selection = self.results_table_Specific.selectionModel()
        for row, column, data in self.clipboard:
            # get the index, with rows and columns relative to the current
            index = self.model.index(firstRow + row, firstColumn + column)
            # set the data for the index
            self.model.setData(index, data, QtCore.Qt.DisplayRole)
            # add the index to the selection
            selection.select(index, selection.Select)

        # apply the selection model
        self.results_table_Specific.setSelectionModel(selection)

I tried this

it's me answering my question, here is the code that I used to get a QTableWidget with the copy/paste options outside and within the App, with two possibilities, with ContextMenu and KeyPress. in addition to the answer I linked above on the post here are the links to other posts where I found some help link1 link2

class Calculation_window_Specific(QMainWindow):
    def __init__(self):
        super().__init__()
        uic.loadUi("specific_calculation_window.ui",self)
        self.setStyleSheet(stylesheet2)
        self.setWindowTitle('specific calculation table')
        self.setWindowIcon(QtGui.QIcon("logo.ico"))
        self.actionExcel_xlsx.triggered.connect(self.Export_to_Excel2) 

        self.results_table_Specific.installEventFilter(self)  
             
    def eventFilter(self,source,event):
        if event.type()== QtCore.QEvent.KeyPress:
            if event==QtGui.QKeySequence.Copy:
                self.copySelection()
                return True
            elif event==QtGui.QKeySequence.Paste:
                self.pasteSelection()
                return True
        elif event.type() == QtCore.QEvent.ContextMenu:
            # a context menu for the copy/paste operations
            menu = QtWidgets.QMenu()
            copyAction = menu.addAction('Copy')
            copyAction.triggered.connect(self.copySelection)
            pasteAction = menu.addAction('Paste')
            pasteAction.triggered.connect(self.pasteSelection)

            if not self.results_table_Specific.selectedIndexes():
                # no selection available, both copy and paste are disabled
                copyAction.setEnabled(False)
                pasteAction.setEnabled(False)
            menu.exec(event.globalPos())
            return True
        return super(Calculation_window_Specific, self).eventFilter(source, event)
    
    def copySelection(self):
        # clear the current contents of the clipboard
        self.clipboard=''
        copied_cells = sorted(self.results_table_Specific.selectedIndexes())
        max_column = copied_cells[-1].column()
        for c in copied_cells:
            self.clipboard += self.results_table_Specific.item(c.row(), c.column()).text()
            if c.column() == max_column:
                self.clipboard += '\n'
            else:
                self.clipboard += '\t'
        QApplication.clipboard().setText(self.clipboard)

    def pasteSelection(self):
        selection = self.results_table_Specific.selectedIndexes()

        if selection:
            row_anchor = selection[0].row()
            column_anchor = selection[0].column()

            clipboard = QApplication.clipboard()

            rows = clipboard.text().split('\n')
            for indx_row, row in enumerate(rows):
                values = row.split('\t')
                for indx_col, value in enumerate(values):
                    item = QTableWidgetItem(value)
                    self.results_table_Specific.setItem(row_anchor + indx_row, column_anchor + indx_col, item)


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM