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

PySide6 QTextEdit图文复制到MS Word后图片不显示问题求助

解决PySide6 QTextEdit图文复制到Word/Stack Overflow的问题

默认QTextEdit复制图文时,仅提供Qt内部的MIME格式,Word、Stack Overflow等外部应用无法识别其中的图片。要解决这个问题,需要从图片插入方式和复制时的剪贴板格式处理两方面入手:

1. 正确嵌入图片到QTextEdit

直接插入图片时,要确保图片数据内嵌到文档中,而非仅引用外部路径。可以通过QTextDocument.addResource将图片作为资源添加,再用QTextImageFormat插入:

import uuid
from PySide6.QtGui import QImage, QTextDocument, QTextImageFormat, QTextCursor
from PySide6.QtWidgets import QTextEdit

class MyTextEdit(QTextEdit):
    def insert_image(self, image_path):
        doc = self.document()
        image = QImage(image_path)
        if image.isNull():
            return
        
        # 生成唯一资源ID,避免冲突
        resource_url = f"img_{uuid.uuid4()}"
        # 将图片添加为文档资源
        doc.addResource(QTextDocument.ImageResource, QUrl(resource_url), image)
        
        # 创建图片格式并插入
        img_format = QTextImageFormat()
        img_format.setName(resource_url)
        # 可选:设置图片大小
        img_format.setWidth(image.width() // 2)
        img_format.setHeight(image.height() // 2)
        
        cursor = self.textCursor()
        cursor.insertImage(img_format)
        self.setTextCursor(cursor)

2. 重写复制逻辑,生成兼容格式的剪贴板数据

重写copy方法,将选中内容转换为带内嵌图片的HTML(Stack Overflow支持)和RTF(Word更兼容),同时保留纯文本和原始图片数据:

from PySide6.QtCore import QMimeData, QBuffer, QIODevice, QUrl
from PySide6.QtWidgets import QApplication
import re

class MyTextEdit(QTextEdit):
    # (保留上面的insert_image方法)
    
    def get_embedded_html(self):
        """将文档中的图片资源转为base64内嵌的HTML"""
        doc = self.document()
        html = doc.toHtml()
        
        # 替换Qt资源URL为base64编码的图片数据
        def replace_img_tag(match):
            resource_url = match.group(1)
            resource = doc.resource(QTextDocument.ImageResource, QUrl(resource_url))
            if isinstance(resource, QImage):
                buffer = QBuffer()
                buffer.open(QIODevice.WriteOnly)
                resource.save(buffer, "PNG")
                base64_data = buffer.data().toBase64().data().decode()
                return f'<img src="data:image/png;base64,{base64_data}"'
            return match.group(0)
        
        return re.sub(r'<img src="([^"]+)"', replace_img_tag, html)
    
    def copy(self):
        mime_data = QMimeData()
        selected_text = self.textCursor().selectedText()
        
        # 添加纯文本格式
        mime_data.setText(selected_text)
        
        # 添加带内嵌图片的HTML
        embedded_html = self.get_embedded_html()
        mime_data.setHtml(embedded_html)
        
        # 可选:添加RTF格式(需依赖pypandoc)
        # 安装:pip install pypandoc,同时需安装pandoc工具
        # import pypandoc
        # rtf_content = pypandoc.convert_text(embedded_html, 'rtf', format='html')
        # mime_data.setData("text/rtf", rtf_content.encode())
        
        # 添加原始图片数据(部分应用支持)
        cursor = self.textCursor()
        if cursor.hasSelection():
            fragment = cursor.selection()
            for block in [fragment.begin().block(), fragment.end().block()]:
                it = block.begin()
                while not it.atEnd():
                    char_format = it.charFormat()
                    if char_format.isImageFormat():
                        img_format = char_format.toImageFormat()
                        resource = self.document().resource(QTextDocument.ImageResource, QUrl(img_format.name()))
                        if isinstance(resource, QImage):
                            buffer = QBuffer()
                            buffer.open(QIODevice.WriteOnly)
                            resource.save(buffer, "PNG")
                            mime_data.setData("image/png", buffer.data())
                            break
                    it += 1
        
        # 更新剪贴板
        QApplication.clipboard().setMimeData(mime_data)

3. 使用自定义TextEdit

如果是通过Qt Designer创建的QTextEdit,需要将其提升为MyTextEdit类:

  1. 在Qt Designer中选中QTextEdit
  2. 右键选择「提升为...」
  3. 输入提升的类名称MyTextEdit,头文件填写对应的Python文件名(如my_text_edit.py)
  4. 点击「添加」并「提升」

效果说明

  • 复制到Word:Word会识别HTML或RTF格式,正确显示内嵌图片
  • 复制到Stack Overflow:Stack Overflow支持base64内嵌的HTML图片,粘贴后直接显示图片而非占位符

内容的提问来源于stack exchange,提问作者HyoSeok Jeon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:53:15