From the documentation :
Embedded images are represented by the object replacement symbol (0xFFFC in Unicode), which has a QTextImageFormat associated with it. The image format is indicated by the name using setName (), which is used to search for the image.
You can use charFormat().toImageFormat().name()
on the cursor to retrieve the URL of the image. The following is a self-sufficient example. There are two notable details:
The cursor sometimes points to one character in front of the image. Thus, a workaround; this seems to be necessary for both Qt 4.8.5 and 5.1.1.
Pop-up menus should be displayed asynchronously so as not to block the rest of the application. The sample code provided in the documentation is a source of bad user experience and should be considered an evil abomination. All widgets can automatically delete themselves when they close, so the menu will not flow. A QPointer
used only to demonstrate this fact. It keeps track of the lifetime of the menu and is zero when the menu deletes itself.
#include <QApplication> #include <QTextBrowser> #include <QImage> #include <QPainter> #include <QMenu> #include <QContextMenuEvent> #include <QTextBlock> #include <QPointer> #include <QDebug> class Browser : public QTextBrowser { QPointer<QMenu> m_menu; protected: void contextMenuEvent(QContextMenuEvent *ev) { Q_ASSERT(m_menu.isNull()); // make sure the menus aren't leaking m_menu = createStandardContextMenu(); QTextCursor cur = cursorForPosition(ev->pos()); QTextCharFormat fmt = cur.charFormat(); qDebug() << "position in block" << cur.positionInBlock() << "object type" << cur.charFormat().objectType(); if (fmt.objectType() == QTextFormat::NoObject) { // workaround, sometimes the cursor will point one object to the left of the image cur.movePosition(QTextCursor::NextCharacter); fmt = cur.charFormat(); } if (fmt.isImageFormat()) { QTextImageFormat ifmt = fmt.toImageFormat(); m_menu->addAction(QString("Image URL: %1").arg(ifmt.name())); } m_menu->move(ev->globalPos()); m_menu->setAttribute(Qt::WA_DeleteOnClose); // the menu won't leak m_menu->show(); // show the menu asynchronously so as not to block the application } }; void addImage(QTextDocument * doc, const QString & url) { QImage img(100, 100, QImage::Format_ARGB32_Premultiplied); img.fill(Qt::white); QPainter p(&img); p.drawRect(0, 0, 99, 99); p.drawText(img.rect(), url); doc->addResource(QTextDocument::ImageResource, QUrl(url), img); } int main(int argc, char *argv[]) { QApplication a(argc, argv); QTextDocument doc; Browser browser; doc.setHtml("<img src=\"data://image1\"/><br/><img src=\"data://image2\"/>"); addImage(&doc, "data://image1"); addImage(&doc, "data://image2"); browser.show(); browser.setDocument(&doc); return a.exec(); }
source share