how to paste and copy out multiple cells values in qt table widget

萝らか妹 提交于 2021-02-11 12:31:54

问题


I am very new in programming. Please help me in this regards. Thanks in advance.

Here is my code:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):

    def clear_table(self):
        self.tableWidget_2.clearContents()

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1920, 1080)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget_2 = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget_2.setGeometry(QtCore.QRect(10, 100, 1800, 700))
        self.tableWidget_2.setObjectName("tableWidget_2")
        self.tableWidget_2.setColumnCount(3)
        self.tableWidget_2.setRowCount(500)
        # self.tableWidget_2.cellChanged.connect(self.c_current)
        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(300, 20, 150, 50))
        self.pushButton_2.setText("Import table")
        self.pushButton_2.setObjectName("pushButton_2")

        #####
        ###
        self.pushButton = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(10, 20, 150, 50))
        self.pushButton.setText("Clear table")
        self.pushButton.clicked.connect(self.clear_table)
        self.pushButton.setObjectName("pushButton")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 18))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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_())

output table:

enter image description here

For example, I want to paste this data table into the qt widget table:

1 2 3 
6 7 8 
10 11 12

Similarly I also want to copy out the whole data from qt table using CLT+C or mouse right button click and the copy. like this:

enter image description here


回答1:


If you only need internal copy and paste operations, you can use a local variable to store the item data (row, column and content), then use an event filter to trigger those operations.

In the following example I created two simple functions that can be called when using the keyboard shortcuts (ctrl+c or ctrl+v) or through a context menu.

When one or more items are selected, they can be copied.
If the "clipboard" has contents and one index is selected (the "current index"), those contents will be pasted relative to it.

from PyQt5 import QtCore, QtGui, QtWidgets

class Window(QtWidgets.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        self.model = QtGui.QStandardItemModel(10, 10)
        self.tableView = QtWidgets.QTableView()
        self.tableView.setModel(self.model)

        self.tableView.installEventFilter(self)
        layout = QtWidgets.QVBoxLayout(self)
        layout.addWidget(self.tableView)

        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.tableView.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(Window, self).eventFilter(source, event)

    def copySelection(self):
        # clear the current contents of the clipboard
        self.clipboard.clear()
        selected = self.tableView.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.tableView.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.tableView.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.tableView.setSelectionModel(selection)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

Note that I didn't use your code, as that is the output generated from pyuic, which should never be modified. Those files are only meant to be imported, and the program logic must be implemented on a separate script. Read the documentation about using Designer to know how to correctly use UI files, otherwise just create the interface by subclassing the qwidget as done in my example.



来源:https://stackoverflow.com/questions/62993930/how-to-paste-and-copy-out-multiple-cells-values-in-qt-table-widget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!