Copy/Paste multiple items from QTableView in pyqt4

2020-02-01 18:04发布

We can select multiple items(partial rows and partial columns) from QTableView using self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection), but after selecting some rows and columns(partial and partial) if I do CTRL+C and paste it in notepad it only pastes one item(one value from the tableView)?

My Code:

tab_table_view = QtGui.QWidget()
self.Tab.insertTab(0, tab_table_view, self.File_Name)
self.tableView = QtGui.QTableView(tab_table_view)
self.tableView.setGeometry(QtCore.QRect(0, 0, 721, 571))
self.model = QtGui.QStandardItemModel(self)
self.model.setSortRole(QtCore.Qt.UserRole)
self.tableView.setModel(self.model)

    self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection) '''this helps for selecting multiple items but not able to copy and paste multiple values to a text/ excel (it only copies single value)'''

How can we do copy and paste multiple items?

3条回答
▲ chillily
2楼-- · 2020-02-01 18:22

QAbstractItemView.ExtendedSelection When the user selects an item in the usual way, the selection is cleared and the new item selected. However, if the user presses the Ctrl key when clicking on an item, the clicked item gets toggled and all other items are left untouched. If the user presses the Shift key while clicking on an item, all items between the current item and the clicked item are selected or unselected, depending on the state of the clicked item. Multiple items can be selected by dragging the mouse over them. you can also use

QAbstractItemView.MultiSelection
查看更多
Summer. ? 凉城
3楼-- · 2020-02-01 18:25

Many thanks to @learncode comment above, I manage to get the copy part. Moverover, I modify a bit to support copy to Excel with corresponding order of cells:

def copySelection(self):
    selection = self.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, delimiter='\t').writerows(table)
        QtWidgets.qApp.clipboard().setText(stream.getvalue())
    return

In addition to copy, I also create the paste part. Depending the range of cell user selected (one cell or range of cell), this snippet supports pasting of different shape of data.

def pasteSelection(self):
    selection = self.selectedIndexes()
    if selection:
        model = self.model()

        buffer = QtWidgets.qApp.clipboard().text() 
        rows = sorted(index.row() for index in selection)
        columns = sorted(index.column() for index in selection)
        reader = csv.reader(io.StringIO(buffer), delimiter='\t')
        if len(rows) == 1 and len(columns) == 1:
            for i, line in enumerate(reader):
                for j, cell in enumerate(line):
                    model.setData(model.index(rows[0]+i,columns[0]+j), cell)
        else:
            arr = [ [ cell for cell in row ] for row in reader]
            for index in selection:
                row = index.row() - rows[0]
                column = index.column() - columns[0]
                model.setData(model.index(index.row(), index.column()), arr[row][column])
    return
查看更多
聊天终结者
4楼-- · 2020-02-01 18:42
self.tableView.installEventFilters(self)

Now, adding event filter:

def eventFilter(self, source, event):
        if (event.type() == QtCore.QEvent.KeyPress and
            event.matches(QtGui.QKeySequence.Copy)):
            self.copySelection()
            return True
        return super(Window, self).eventFilter(source, event)

Copy Function:

def copySelection(self):
        selection = self.tableView.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)
            QtGui.qApp.clipboard().setText(stream.getvalue())

Answered by ekhumoro, for the same question asked again.

查看更多
登录 后发表回答