【问题标题】:is there any way to insert QPixmap object in html?有没有办法在 html 中插入 QPixmap 对象?
【发布时间】:2011-09-29 17:23:53
【问题描述】:

简单情况:我有一个对象,它有一个QPixmap 成员。首先创建对象(现在像素图为空),然后从数据库中读取像素图并插入对象中。我需要在 html 代码 () 中插入该像素图并在 QLabel 中显示该 html 代码,但我不知道如何制作它,因为像素图的路径是未知的。

我知道如何从资源文件和硬盘上的文件中插入图像,但事实并非如此。我在 qt 3.3.4 上使用 QMimeSourceFactory 类,但在 4.6.2 上它已被弃用。助理说:“改用资源系统”。但是资源系统是用app编译的,但是需要在运行时读取图片。

如果有任何帮助,我将不胜感激。谢谢。

【问题讨论】:

    标签: html qt qpixmap


    【解决方案1】:

    如果你只想在 QLabel 中显示 QPixmap,你应该使用 QLabel::setPixmap。您可以使用 QPixmap::loadFromData 在内存中构建像素图。

    如果您想在 HTML 中显示内存像素图,例如在 QWebView 中,您可以使用

        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        pixmap.save(&buffer, "PNG");
        QString url = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/>";
    

    (未经测试)

    QLabel::setText 不适用于 HTML,但适用于富文本。我不知道 Qt 富文本实现是否支持 data: 协议。

    另一种将像素图插入 QWebView 的方法是使用 QNetworkAccessManager 的子类并重新实现它的 createRequest() 函数以使用您自己的协议(“myprot:”)检查 URL 并在其中插入像素图数据。但这看起来有点矫枉过正。

    【讨论】:

    • 这个想法是在小部件中显示该图片,它可以通过插入html代码img标签来显示html内容(例如:QWhatsThis、QLabel等)。这么好的方法(重新实现QNetworkAccessManager,使用QLabel::setPixmap(),使用QWebView)——这不是我需要的。虽然他们很好。我已经测试了你的方法,但它仍然没有帮助。图片不显示=/
    • 你试试数据:你用 QLabel::setTextFormat(Qt::RichText) 和 QLabel::setText 设置的带有 html 代码的 URL?
    • 是的,当然。在之前的评论中,我已经提到了这一点。 QWhatsThis 和 QLabel 都不会显示带有数据 url 的图像。我尝试了一些如何在运行时向应用程序添加新资源,因此新图像将具有与其他图像一样的资源地址,在编译时链接,但仍然没有运气。
    【解决方案2】:

    我把它放在另一个答案中以便能够格式化代码。我编写了以下程序,它按预期工作:

    #include <QtGui>
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
        QWidget window;
        window.resize(320, 240);
        window.show();
        window.setWindowTitle(
            QApplication::translate("toplevel", "Top-level widget"));
        QLabel* label = new QLabel(&window);
        label->setTextFormat(Qt::RichText);
        QString text = "<html><h1>Test</h1>here is an image: ";
        QPixmap pixmap("testicon.jpg");
        QByteArray byteArray;
        QBuffer buffer(&byteArray);
        pixmap.save(&buffer, "PNG");
        QString url = QString("<img src=\"data:image/png;base64,") + byteArray.toBase64() + "\"/>";
        text += url;
        text += "</html>";
        label->setText(text);
    
        label->move(100, 100);
        label->show();
        return app.exec();
    }
    

    【讨论】:

    • 不。那里没有变化。以字节数组加载图像 - 应用程序停止用户交互,但仍不显示图像。尝试使用 jpg 和 png 的...你的 Qt 版本是什么?我的是4.6.2。可能您有 4.7.x,这就是为什么它可以在您的机器上运行的原因......但是感谢您的帮助。我想知道,有没有其他方法可以做到这一点
    • 我可以确认这对我有用。感谢您提供全面的 sn-p,@hmuelner!
    • 对我也很好。我使用 QTextDocumentFragment 在现有文本中插入图像,而不覆盖现有内容。
    【解决方案3】:

    我知道这是一个老问题,但这里有另一种选择。

    QToolTip 中的图片也有类似的问题。我可以很好地引用磁盘中的图像,但默认的缩放行为不流畅而且看起来很糟糕。我重新实现了自己的工具提示类并使用了自定义的QTextDocument 类,以便我可以覆盖QTextDocument::loadResource()

    在您的情况下,您可以在 img src 属性中指定一个关键字。然后在 loadResource() 的实现中返回用关键字标识的 QPixmap。

    这是基本代码(在此上下文中未经测试):

    class MyTextDocument : public QTextDocument
    {
    protected:
      virtual QVariant loadResource(int type, const QUrl &name)
      {
        QString t = name.toString();
        if (t == myKeyword)
          return myPixmap;
        return QTextDocument::loadResource(type, name);
      }
    };
    
    class MyLabel : public QFrame
    {
    public:
      MyLabel(QWidget *parent)
      : QFrame(parent)
      , m_doc(new MyTextDocument(this))
      { }
    
      virtual void paintEvent(QPaintEvent *e)
      {
        QStylePainter p(this);
        // draw the frame if needed
    
        // draw the contents
        m_doc->drawContents(&p);
      }
    };
    

    【讨论】:

    【解决方案4】:

    这是我关于将 QPixmap 序列化/反序列化到 Base64 e 字符串的两分钱。我已经包含了将图像加载/保存为文本文件的方法,还有两个简单的 toBase64()fromBase64() 有助于 HTML、SQL 或 JSON 编码。

    #include "b64utils.h"
    #include <QBuffer>
    #include <QFile>
    #include <QTextStream>
    
    /**
     * Serializes a QPixmap object into a Base64 string
     */
    QString B64Utils::toBase64(QPixmap *pixmap) {
        // Convert the pixel map into a base64 byte array
        QBuffer *buffer = new QBuffer;
        pixmap->save(buffer, "png");
        QByteArray b64 = buffer->data().toBase64();
        QString *b64Str = new QString(b64);
        return *b64Str;
    }
    
    /**
     * Serializes a QPixmap object into a Base64 string and save it to a file
     */
    bool B64Utils::savePixmapToBase64(QPixmap *pixmap, QString filePath) {
        // Opens a file for writing text
        QFile file(filePath);
        if (!file.open(QIODevice::WriteOnly | QFile::Text)) return false;
    
        // Write the Base64 string into the file
        QTextStream stream(&file);
        stream << toBase64(pixmap);
        file.close();
    
        return true;
    }
    
    /**
     * Deserializes a Base64 string, representing an image, into a QPixmap
     */
    QPixmap* B64Utils::fromBase64(QString b64Str) {
        QPixmap *pixmap = new QPixmap;
        pixmap->loadFromData(QByteArray::fromBase64(b64Str.toUtf8()));
        return pixmap;
    }
    
    /**
     * Retrieves a Base64 string, representing an image, from a file and deserializes it into a QPixmap
     */
    QPixmap* B64Utils::loadPixmapFromBase64(QString filePath) {
        // Opens a file for reading text
        QFile file(filePath);
        if (!file.open(QFile::ReadOnly | QFile::Text)) return nullptr;
    
        // Reads the contents of the file into a string
        QTextStream in(&file);
        QString b64Str = in.readAll();
        file.close();
    
        return fromBase64(b64Str);
    }
    

    【讨论】:

    • 为什么这里会出现关于另一个 SO 问题的评论?
    • 好的,但我的编辑出了什么问题?提到InterruptException 是不正确的
    • 对不起,我只是为了完成评论被接受所需的 6 个字符
    • 是的!我也很惊讶。感谢您的支持。我已经完成了。
    猜你喜欢
    • 2010-12-04
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多