You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在数据源为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 19:48:03