如何在数据源为pandas dataframe的QTableView中复制粘贴多行多列?
PyQt5 QTableView 实现带表头/行索引的复制功能
你只需要补全自定义QTableView子类的复制事件处理逻辑即可,修改后完整可运行代码如下:
import sys from PyQt5 import QtCore, QtGui, QtWidgets from PyQt5.QtCore import Qt from PyQt5.QtGui import QKeySequence from PyQt5.QtWidgets import QApplication, QTableView import pandas as pd class TableModel(QtCore.QAbstractTableModel): def __init__(self, data): super(TableModel, self).__init__() self._data = data def data(self, index, role): if role == Qt.DisplayRole: value = self._data.iloc[index.row(), index.column()] return str(value) def rowCount(self, index): return self._data.shape[0] def columnCount(self, index): return self._data.shape[1] def headerData(self, section, orientation, role): if role == Qt.DisplayRole: if orientation == Qt.Horizontal: return str(self._data.columns[section]) if orientation == Qt.Vertical: return str(self._data.index[section]) class View(QTableView): def __init__(self): super(View, self).__init__(parent=None) def keyPressEvent(self, event): if event.matches(QKeySequence.Copy): selected_indexes = self.selectedIndexes() if not selected_indexes: return super().keyPressEvent(event) # 提取选中的行、列,去重排序 selected_rows = sorted(set(idx.row() for idx in selected_indexes)) selected_cols = sorted(set(idx.column() for idx in selected_indexes)) # 拼接列表头行,第一格为空对应行索引列的表头位置 header_row = [''] + [self.model().headerData(col, Qt.Horizontal, Qt.DisplayRole) for col in selected_cols] copy_content = ['\t'.join(header_row)] # 拼接每行内容,开头加行索引 for row in selected_rows: current_row = [self.model().headerData(row, Qt.Vertical, Qt.DisplayRole)] for col in selected_cols: cell_idx = self.model().index(row, col) current_row.append(self.model().data(cell_idx, Qt.DisplayRole)) copy_content.append('\t'.join(current_row)) # 写入剪贴板 QApplication.clipboard().setText('\n'.join(copy_content)) event.accept() return # 其他事件走默认逻辑 super().keyPressEvent(event) class MainWindow(QtWidgets.QMainWindow): def __init__(self): super().__init__() self.table = View() data = pd.DataFrame([ [1, 9, 2], [1, 0, -1], [3, 5, 2], [3, 3, 2], [5, 8, 9], ], columns = ['A', 'B', 'C'], index=['Row 1', 'Row 2', 'Row 3', 'Row 4', 'Row 5']) self.model = TableModel(data) self.table.setModel(self.model) self.setCentralWidget(self.table) self.resize(500, 300) if __name__ == '__main__': app = QtWidgets.QApplication(sys.argv) window = MainWindow() window.show() app.exec_()
关键逻辑说明
- 选中区域处理:自动提取所有选中单元格的行号、列号,去重后按表格显示顺序排序,支持连续/非连续选中区域的复制
- 内容格式:使用制表符
\t分隔列、换行符\n分隔行,复制后的内容可以直接粘贴到Excel、WPS、记事本等工具中,保持原有排版 - 事件处理:复制逻辑执行完成后调用
event.accept()终止事件传播,避免触发QTableView默认的无表头复制逻辑
内容的提问来源于stack exchange,提问作者wwj123
相关产品推荐
相关产品推荐

