从pyqt4中的QTableView复制/粘贴多个项目?

问题描述 投票:1回答:3

我们可以使用self.tableView.setSelectionMode(QAbstractItemView.ExtendedSelection)从QTableView中选择多个项目(部分行和部分列),但是在选择了一些行和列(部分和部分)之后,如果我执行CTRL + C并将其粘贴到记事本中,它只会粘贴一个项目(一个值来自的tableView)?

我的代码:

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)'''

我们如何复制和粘贴多个项目?

python pyqt4 copy-paste qtableview qabstractitemview
3个回答
3
投票
self.tableView.installEventFilters(self)

现在,添加事件过滤器:

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)

复制功能:

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

由ekhumoro回答,同样的问题再次提出。


1
投票

QAbstractItemView.ExtendedSelection当用户以通常的方式选择项目时,将清除选择并选择新项目。但是,如果用户在单击某个项目时按下Ctrl键,则单击的项目将切换,所有其他项目保持不变。如果用户在单击项目时按下Shift键,则根据所单击项目的状态选择或取消选择当前项目和单击项目之间的所有项目。可以通过将鼠标拖过它们来选择多个项目。你也可以用

QAbstractItemView.MultiSelection

0
投票

非常感谢上面的@learncode评论,我设法获得了复制部分。 Moverover,我修改了一下以支持复制到Excel并具有相应的单元格顺序:

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

除了复制,我还创建了粘贴部分。根据所选单元格用户的范围(一个单元格或单元格范围),此代码段支持粘贴不同形状的数据。

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
© www.soinside.com 2019 - 2024. All rights reserved.