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类:
- 在Qt Designer中选中QTextEdit
- 右键选择「提升为...」
- 输入提升的类名称
MyTextEdit,头文件填写对应的Python文件名(如my_text_edit.py) - 点击「添加」并「提升」
效果说明
- 复制到Word:Word会识别HTML或RTF格式,正确显示内嵌图片
- 复制到Stack Overflow:Stack Overflow支持base64内嵌的HTML图片,粘贴后直接显示图片而非占位符
内容的提问来源于stack exchange,提问作者HyoSeok Jeon
相关产品推荐
相关产品推荐

