qt 图文混排

'm still quite a newbie with Python and PyQt so I have a really basic question. I have some text and images in a parent window inside a QTextEdit widget and I'm trying to copy all the content to a child window's QTextEdit. But for some reason I can't get it to copy the image - only the text is copied not the image. Here's a snippet of the code that's giving me trouble:

self.textEdit.selectAll() data = self.textEdit.createMimeDataFromSelection() self.child_window.textEdit.insertFromMimeData(data) # doesn't work with images

Here's is the small program that I'm trying to run:

import sys from PyQt4 import QtCore, QtGui from PyQt4.QtCore import * from PyQt4.QtGui import * class MyWindow(QtGui.QWidget): def __init__(self,parent=None): super(MyWindow,self).__init__(parent) self.textEdit = QtGui.QTextEdit(self) self.textEdit.setText("Hello World\n") self.pushButton = QtGui.QPushButton(self) self.pushButton.setText("Copy and paste to Child Window") self.pushButton.clicked.connect(self.click_copy_data) self.pushButton2 = QtGui.QPushButton(self) self.pushButton2.setText("Insert Image") self.pushButton2.clicked.connect(self.click_file_dialog) self.layoutVertical = QtGui.QVBoxLayout(self) self.layoutVertical.addWidget(self.textEdit) self.layoutVertical.addWidget(self.pushButton2) self.layoutVertical.addWidget(self.pushButton) self.setGeometry(150, 150,640, 480) self.child_window = CustomWindow(self) self.child_window.show() def click_copy_data(self): self.textEdit.selectAll() data = self.textEdit.createMimeDataFromSelection() self.child_window.textEdit.insertFromMimeData(data) def click_file_dialog(self): filePath = QtGui.QFileDialog.getOpenFileName( self, "Select an image", ".", "Image Files(*.png *.gif *.jpg *jpeg *.bmp)" ) if not filePath.isEmpty(): self.insertImage(filePath) def insertImage(self,filePath): imageUri = QtCore.QUrl(QtCore.QString("file://{0}".format(filePath))) image = QtGui.QImage(QtGui.QImageReader(filePath).read()) self.textEdit.document().addResource( QtGui.QTextDocument.ImageResource, imageUri, QtCore.QVariant(image) ) imageFormat = QtGui.QTextImageFormat() imageFormat.setWidth(image.width()) imageFormat.setHeight(image.height()) imageFormat.setName(imageUri.toString()) textCursor = self.textEdit.textCursor() textCursor.movePosition( QtGui.QTextCursor.End, QtGui.QTextCursor.MoveAnchor ) textCursor.insertImage(imageFormat) # This will hide the cursor blankCursor = QtGui.QCursor(QtCore.Qt.BlankCursor) self.textEdit.setCursor(blankCursor) class CustomWindow(QtGui.QDialog): def __init__(self,parent=None): super(CustomWindow,self).__init__(parent) self.textEdit = QtGui.QTextEdit(self) self.layoutVertical = QtGui.QVBoxLayout(self) self.layoutVertical.addWidget(self.textEdit) if __name__ == "__main__": app = QtGui.QApplication(sys.argv) app.setApplicationName('MyWindow') main = MyWindow() main.show() sys.exit(app.exec_())

The way the program works is that you have some text inside the main window and then you insert an image. Then you click "Copy and paste to Child Window" button and it should paste all the contents to the child, including the image - but that doesn't work that way it's supposed to - the text is copied but I get a little file icon where the image should be.

I would appreciate your help on this.

Paul

share | improve this question
  add comment

2 Answers

active oldest votes
up vote 1 down vote

QTextEdit doesn't decode image MIME types by default, so just subclass it to add support, you'll need to reimplement canInsertFromMimeData and insertFromMimeData, also try QTextBrowserinstead. Just add this to your script:

class MyTextBrowser(QtGui.QTextBrowser): def __init__(self, parent=None): super(MyTextBrowser, self).__init__(parent) self.setReadOnly(False) def canInsertFromMimeData(self, source): if source.hasImage(): return True else: return super(MyTextBrowser, self).canInsertFromMimeData(source) def insertFromMimeData(self, source): if source.hasImage(): image = QtCore.QVariant(source.imageData()) document = self.document() document.addResource( QtGui.QTextDocument.ImageResource, QtCore.QUrl("image"), image ) cursor = self.textCursor() cursor.insertImage("image") super(MyTextBrowser, self).insertFromMimeData(source)

And change self.textEdit = QtGui.QTextEdit(self) into self.textEdit = MyTextBrowser(self) on both widgets.

share | improve this answer
 
 
This is strange. For some reason source.hasImage() doesn't return True. Even when I try a .jpg or .png file. –  Paul  Mar 24 at 0:54
 
this is what I tried: print "has image?", data.hasImage(). I get False. –   Paul  Mar 24 at 0:56
1  
That's because an html MIME type is being used, it is kind like if you where saying mimedata = textEdit.toHtml() and textEdit.setHtml(mimedata) –   X.Jacobs  Mar 24 at 1:15 
 
Sorry but how can I implement the behavior of copying text AND images inside QTextEdit field using QMimeData? I am still a newb so I don't fully quite understand the documentation. –   Paul  Mar 24 at 2:13
1  
That's exactly what you are doing, using an html MIME type. If you want to use a different MIME type you'll have to implement it yourself, possibly iterating over the elements on your document and checking their types. Note that QMimeData is usually used to supply data to the QDrag or QClipboard objects, using the toHtml method would be much more convenient in your case. –   X.Jacobs  Mar 24 at 12:39 
show 1 more comment




think this is a very simple question, but when I copy an image I can't paste it in a QTextEdit? Paste is inactive! Also I would like to know how to drag-and-drop a picture.

BTW I use the following code in order to insert a picture into a QTextEdit:

QTextEdit *textEditor = new QTextEdit(0); QTextDocumentFragment fragment; fragment = QTextDocumentFragment::fromHtml("<img src='C:\\aaa.jpg'>"); textEditor->textCursor().insertFragment(fragment); textEditor->setVisible(true);

Is it recommended? How do you do this operation?

share | improve this question
  add comment

1 Answer

active oldest votes
up vote 11 down vote accepted

The second way is this:

void TextEdit::insertImage() { QString file = QFileDialog::getOpenFileName(this, tr("Select an image"), ".", tr("Bitmap Files (*.bmp)\n" "JPEG (*.jpg *jpeg)\n" "GIF (*.gif)\n" "PNG (*.png)\n")); QUrl Uri ( QString ( "file://%1" ).arg ( file ) ); QImage image = QImageReader ( file ).read(); QTextDocument * textDocument = m_textEdit->document(); textDocument->addResource( QTextDocument::ImageResource, Uri, QVariant ( image ) ); QTextCursor cursor = m_textEdit->textCursor(); QTextImageFormat imageFormat; imageFormat.setWidth( image.width() ); imageFormat.setHeight( image.height() ); imageFormat.setName( Uri.toString() ); cursor.insertImage(imageFormat); }

The third way is to inherit QTextEdit and reimplement bool canInsertFromMimeData(const QMimeDatasource) const* and void insertFromMimeData(const QMimeData source)* functions as followes. Buy the way this method allows to use drag-and-drop or copy-paste mechanisms.

class TextEdit : public QTextEdit { public: bool canInsertFromMimeData(const QMimeData* source) const { return source->hasImage() || source->hasUrls() || QTextEdit::canInsertFromMimeData(source); } void insertFromMimeData(const QMimeData* source) { if (source->hasImage()) { static int i = 1; QUrl url(QString("dropped_image_%1").arg(i++)); dropImage(url, qvariant_cast<QImage>(source->imageData())); } else if (source->hasUrls()) { foreach (QUrl url, source->urls()) { QFileInfo info(url.toLocalFile()); if (QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1())) dropImage(url, QImage(info.filePath())); else dropTextFile(url); } } else { QTextEdit::insertFromMimeData(source); } } private: void dropImage(const QUrl& url, const QImage& image) { if (!image.isNull()) { document()->addResource(QTextDocument::ImageResource, url, image); textCursor().insertImage(url.toString()); } } void dropTextFile(const QUrl& url) { QFile file(url.toLocalFile()); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) textCursor().insertText(file.readAll()); } };



对我有用[0]  丢个板砖[0]  引用 |  举报 |  管理
回复次数:7
CSDN投诉事项说明
对我有用[0]  丢个板砖[0]  引用 |  举报 |  管理
票选博客之星 得下载分 赢精美奖品
对我有用[0]  丢个板砖[0]  引用 |  举报 |  管理
2014年4月微软MVP申请开始啦!
对我有用[0]  丢个板砖[0]  引用 |  举报 |  管理
对我有用[0]  丢个板砖[0]  引用 |  举报 |  管理
对我有用[0]  丢个板砖[0]  引用 |  举报 |  管理

你可能感兴趣的:(qt 图文混排)