当前位置: 首页 > article >正文

PySide6中如何实现TableWidget跨行列粘贴Excel表格内容

实现功能:使用PySide6进行工具开发,通过TableWidget实现跨行列粘贴Excel表格内容。列数是固定的(因为列标题是固定的),而只根据粘贴内容动态增加行数。如果粘贴的内容超出表格列范围,超出的部分会被忽略。

难点:在 PySide6 中,QTableWidget 默认不支持跨行或跨列粘贴内容。要实现跨行列粘贴功能,需要自定义粘贴逻辑。可以通过重写 QTableWidget 的 dropEvent 或 paste 方法来实现。

示例代码如下:

在这里插入图片描述

from PySide6.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QMainWindow, QMenu
from PySide6.QtCore import Qt, QMimeData

class CustomTableWidget(QTableWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 启用拖放和粘贴功能
        self.setAcceptDrops(True)
        self.setSelectionMode(QTableWidget.SelectionMode.ContiguousSelection)

    def paste(self):
        """重写粘贴方法,支持从 Excel 复制的内容"""
        clipboard = QApplication.clipboard()
        mime_data = clipboard.mimeData()

        if mime_data.hasText():
            # 获取剪贴板中的文本内容
            text = mime_data.text()
            # 按行分割(Excel 复制的内容通常以 \n 分隔行)
            rows = text.strip().split('\n')
            # 获取当前选中的起始单元格
            start_row = self.currentRow()
            start_col = self.currentColumn()

            # 动态调整表格的行数
            required_rows = start_row + len(rows)
            if required_rows > self.rowCount():
                self.setRowCount(required_rows)

            for i, row in enumerate(rows):
                if not row.strip():
                    continue  # 跳过空行
                # 按列分割(Excel 复制的内容通常以 \t 分隔列)
                cells = row.split('\t')
                for j, cell in enumerate(cells):
                    # 计算目标单元格的位置
                    target_row = start_row + i
                    target_col = start_col + j
                    # 检查目标单元格是否在表格列范围内
                    if target_col < self.columnCount():
                        # 创建新的 QTableWidgetItem 并设置内容
                        item = QTableWidgetItem(cell.strip())
                        self.setItem(target_row, target_col, item)

    def keyPressEvent(self, event):
        """重写键盘事件,支持 Ctrl+V 粘贴"""
        if event.key() == Qt.Key.Key_V and event.modifiers() == Qt.KeyboardModifier.ControlModifier:
            self.paste()
        else:
            super().keyPressEvent(event)

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTableWidget 动态行粘贴示例")
        self.setGeometry(100, 100, 600, 400)

        # 创建一个空的表格,不指定初始行数,列数固定为 5
        self.table = CustomTableWidget(0, 5, self)  # 0 行,5 列
        self.setCentralWidget(self.table)

        # 设置固定的列标题
        self.table.setHorizontalHeaderLabels(["Col 1", "Col 2", "Col 3", "Col 4", "Col 5"])

        # 启用右键菜单
        self.table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.table.customContextMenuRequested.connect(self.show_context_menu)

    def show_context_menu(self, pos):
        """显示右键菜单"""
        context_menu = QMenu(self)
        add_row_action = context_menu.addAction("增加行")
        paste_action = context_menu.addAction("粘贴")

        # 连接菜单项的信号
        add_row_action.triggered.connect(self.add_row)
        paste_action.triggered.connect(self.table.paste)

        # 显示菜单
        context_menu.exec_(self.table.viewport().mapToGlobal(pos))

    def add_row(self):
        """动态增加行"""
        current_rows = self.table.rowCount()
        self.table.setRowCount(current_rows + 1)
        self.table.setVerticalHeaderLabels([f"Row {i+1}" for i in range(self.table.rowCount())])

if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec())

http://www.kler.cn/a/557421.html

相关文章:

  • 深入理解 JUnit 的 @RunWith 注解与自定义 Runner
  • 【Kafka】Kafka高性能解读
  • DeepSeek 助力 Vue 开发:打造丝滑的二维码生成(QR Code)
  • 【Python爬虫(38)】解锁Scrapy - Redis:构建高效分布式爬虫
  • YOLOv8与DAttention机制的融合:复杂场景下目标检测性能的增强
  • 断开ssh连接程序继续运行
  • 第五届人工智能与工业技术应用国际学术会议(AIITA 2025)
  • 多目标粒子群优化算法-MOPSO-(机器人路径规划/多目标信号处理(图像/音频))
  • 数字后端实现之Innovus中open net原因解析及解决方案
  • 055 SpringCache
  • 【速写】解码与kv-cache的简单细节
  • 网络运维学习笔记 019HCIA-Datacom综合实验03
  • 深度学习技术文章质量提升指南(基于CSDN评分算法优化)
  • 【Java基础-49】Java线程池及其基本应用详解
  • STM32的HAL库开发---单通道ADC过采样实验
  • SAP on Microsoft Azure Architecture and Administration (Ravi Kashyap)
  • C++中数学函数的使用方法
  • sh脚本把服务器B,服务器C目录的文件下载到服务器A目录,添加开机自启动并且一小时执行一次脚本
  • 算法题(75):跳跃游戏
  • 位操作符 练习