本文主要是介绍QTextEdit内拖入图片——QtWidgets,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
前言
QTextEdit是用来编辑和展示文本和富文本的一个控件。我之前一直拿它当纯文本编辑器(QPlainTextEdit)使,一直没啥机会去用一下他的富文本功能。
这次有时间了,准备做一个可以添加图片的编辑框:拖入即可添加到编辑框。
效果图
实现的两种方式
有两种方式,一种是根据动作想到了Drag 、Drop来实现;另一种是QTextEdit自带的方法实现。
拖入、落下事件来实现
一般在光标处添加图片,代码为
QImage img = ...textDocument->addResource(QTextDocument::ImageResource, QUrl("myimage"), img);cursor.insertImage("myimage");
现在我们重写QTextEdit,命名为MyTextEdit,然后在落下事件中,获取MineData,将其转化为QImage,最后根据上面的方法,也就实现了拖入图片功能了
void MyTextEdit::dragEnterEvent(QDragEnterEvent *e)
{e->acceptProposedAction();
}void MyTextEdit::dropEvent(QDropEvent *e)
{QString url=e->mimeData()->urls().first().toLocalFile();if(e->mimeData()->hasImage()){//这只是个名字 供后续调用的名字QUrl name ( QString ( "file://%1" ).arg ( url ) );//获取图片 并插入到光标处QImage image = QImageReader ( url ).read();QTextDocument * textDocument = this->document();document()->addResource( QTextDocument::ImageResource, name, QVariant ( image ) );textCursor().insertImage(name.toString());}
}
QTextEdit自带的方法实现
后来,我发现QTextEdit对插入图片等数据都有固定的方法可实现。通过方法canInsertFromMimeData对插入的数据进行筛选,
然后在insertFromMimeData方法中根据不同类的数据进行操作添加。不过我经过测试发现:source->hasImage()条件的,不知情况下能满足,经过我拖入的或者复制粘贴的,都不是hasImage(),所以谁能解决我的疑问?!
bool MyTextEdit::canInsertFromMimeData(const QMimeData *source) const
{return source->hasImage()||source->hasUrls()||QTextEdit::canInsertFromMimeData(source);}void MyTextEdit::insertFromMimeData(const QMimeData *source)
{if(source->hasImage()){qDebug()<<"hasImage-------------------";static int i=1;QUrl name(QString("imgName_%1").arg(i));QImage img=qvariant_cast<QImage>(source->imageData());document()->addResource(QTextDocument::ImageResource,name,img);textCursor().insertImage(name.toString());i++;}else if (source->hasUrls()){qDebug()<<"urls-----------------------------";foreach (QUrl url, source->urls()){QFileInfo info(url.toLocalFile());if (QImageReader::supportedImageFormats().contains(info.suffix().toLower().toLatin1())){QImage image(info.filePath());if (!image.isNull()){document()->addResource(QTextDocument::ImageResource, url, image);textCursor().insertImage(url.toString());}}else{QFile file(url.toLocalFile());if(file.open(QIODevice::ReadOnly|QIODevice::Text))textCursor().insertText(file.readAll());}}}else{qDebug()<<"insertFromMimeData--------------------";QTextEdit::insertFromMimeData(source);}}
官方源码说明
我在QTextEdit看到了以下一段话,解释了我以上两个方法的可行性:
QTextEdit also supports custom drag and drop behavior. By default, QTextEdit will insert plain text, HTML and rich text when the user drops data of these MIME types onto a document. Reimplement canInsertFromMimeData() and insertFromMimeData() to add support for additional MIME types.
还有我很好奇,QTextEdit底层是如何写的canInsertFromMimeData和insertFromMimeData方法:它是另写了一个控制类QWidgetTextControl来操作,从以下源码中,我们可以清楚的看到它能够支持什么类型插入,还有根据不同的数据类型,进行的不同的处理,这些都是默认自带的。
bool QWidgetTextControl::canInsertFromMimeData(const QMimeData *source) const
{Q_D(const QWidgetTextControl);if (d->acceptRichText)return (source->hasText() && !source->text().isEmpty())|| source->hasHtml()|| source->hasFormat(QLatin1String("application/x-qrichtext"))|| source->hasFormat(QLatin1String("application/x-qt-richtext"));elsereturn source->hasText() && !source->text().isEmpty();
}void QWidgetTextControl::insertFromMimeData(const QMimeData *source)
{Q_D(QWidgetTextControl);if (!(d->interactionFlags & Qt::TextEditable) || !source)return;bool hasData = false;QTextDocumentFragment fragment;
#ifndef QT_NO_TEXTHTMLPARSERif (source->hasFormat(QLatin1String("application/x-qrichtext")) && d->acceptRichText) {// x-qrichtext is always UTF-8 (taken from Qt3 since we don't use it anymore).const QString richtext = QLatin1String("<meta name=\"qrichtext\" content=\"1\" />")+ QString::fromUtf8(source->data(QLatin1String("application/x-qrichtext")));fragment = QTextDocumentFragment::fromHtml(richtext, d->doc);hasData = true;} else if (source->hasHtml() && d->acceptRichText) {fragment = QTextDocumentFragment::fromHtml(source->html(), d->doc);hasData = true;} else {QString text = source->text();if (!text.isNull()) {fragment = QTextDocumentFragment::fromPlainText(text);hasData = true;}}
#elsefragment = QTextDocumentFragment::fromPlainText(source->text());
#endif // QT_NO_TEXTHTMLPARSERif (hasData)d->cursor.insertFragment(fragment);ensureCursorVisible();
}
还有就是QTextEdit支持剪贴板(clipboard)的,从源码中,你可以看到它对复制粘贴等的一系列处理。 这个我就不列举源码了。
结束语
感觉每次深入研究一个经常用的小控件,都收获满满(*^▽^*)!
这篇关于QTextEdit内拖入图片——QtWidgets的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!