{"id":191476,"date":"2013-08-26T22:21:03","date_gmt":"2013-08-26T18:21:03","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=191476"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=191476","title":{"rendered":"<span class=\"post_title\">\u041f\u0435\u0440\u0435\u0445\u0432\u0430\u0442 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0432 QtWebkit<\/span>"},"content":{"rendered":"<div class=\"content html_format\">\n<pre><code>Habrahabr::Instance()-&gt;hello(); <\/code><\/pre>\n<p>  \u042f \u0434\u0430\u0432\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u043b \u043d\u0430 \u0445\u0430\u0431\u0440, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u0432\u043d\u043e. \u041d\u043e \u043d\u0430 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0439 \u043d\u0435\u0434\u0435\u043b\u0435 \u044f \u0438\u0437\u0440\u044f\u0434\u043d\u043e \u043f\u043e\u0442**\u0445\u0430\u043b\u0441\u044f \u0441 \u043c\u043e\u0434\u0443\u043b\u0435\u043c QtWebkit 5.1 \u0438 \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u0442\u043e\u043d\u043e\u043c \u0431\u044b\u043b\u043e \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043a\u0430\u043a\u043e\u0439 \u043c\u0440\u0430\u043a \u0436\u0434\u0435\u0442 \u0432\u0430\u0441 \u0442\u0430\u043c, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u0440\u043e\u0434\u0435.<\/p>\n<p>  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043c\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043b\u0435\u0436\u0430\u043b\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0432\u0441\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u0431\u0440\u0430\u0443\u0437\u0438\u0442. \u042d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434: \u043f\u043e\u0432\u0435\u0441\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0435 QWebElement \u043f\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443 \u201cimg\u201d \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 (QWebElement::render()) \u0447\u0435\u0440\u0435\u0437 QPainter \u043d\u0430 QImage, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b.<\/p>\n<p>  \u041d\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e. \u041f\u0440\u043e \u0442\u043e\u0442 \u043f\u0443\u0442\u044c \u0441\u0430\u043c\u0443\u0440\u0430\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437\u043b\u043e\u0436\u0435\u043d \u043c\u043d\u043e\u0439 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430. \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0430\u043f\u043f\u0435\u0442\u0438\u0442\u0430!<\/p>\n<p>  <a name=\"habracut\"><\/a>  <\/p>\n<h4>\u042d\u0442\u0430\u043f 1. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/h4>\n<p>  \u042f \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0439 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u0430\u0440\u0430\u0433\u0440\u0430\u0444\u0435 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c Qt 5 \u0438\u0437 Git \u043d\u0430 Mac, \u0441\u043e\u0431\u0438\u0440\u0430\u044f Clang 64-bit. \u0412 \u043e\u0431\u0449\u0435\u043c, \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b. \u0412\u0441\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u044b\u043b\u0438 \u043b\u0438\u0431\u043e \u0447\u0435\u0440\u043d\u044b\u043c\u0438 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430\u043c\u0438, \u043b\u0438\u0431\u043e \u0430\u0434\u043e\u0432\u044b\u043c \u0442\u0440\u044d\u0448\u0435\u043c. \u0422\u0443\u0442-\u0442\u043e \u044f \u0438 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043b, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440 (\u0421\u0421\u042b\u041b\u041a\u0410) \u0438\u0437 \u043f\u043e\u0441\u0442\u0430\u0432\u043a\u0438 Qt 5, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b. \u042f \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u043e\u0431\u0440\u0430\u043b \u0435\u0433\u043e \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043b \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a, \u043a\u0430\u043a \u0431\u044b\u043b\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043e \u0432 README. \u041d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041e\u0444\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u0430\u043a \u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e \u2014 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0417\u0430\u0442\u0435\u0441\u0442\u0438\u043b \u043d\u0430 \u043b\u0438\u043d\u0443\u043a\u0441\u0435 \u2014 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e.<\/p>\n<p>  \u0418 \u0447\u0442\u043e \u0436\u0435 \u0434\u0435\u043b\u0430\u0442\u044c? \u0410 \u043d\u0438\u0447\u0435\u0433\u043e, \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u0430 \u0448\u0442\u0443\u043a\u0430 \u0438 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e \u043f\u043e\u0447\u0435\u043c\u0443. \u0423 \u043c\u0435\u043d\u044f \u043d\u0435 \u0431\u044b\u043b\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0438\u0441\u043a\u0430\u043b \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f. \u041f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b, \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043c\u0441\u044c\u0435 \u0438\u0441\u043a\u0443\u0448\u0435\u043d\u0438\u0439 \u0432 \u0441\u0442\u0443\u0434\u0438\u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435\u0439 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043d\u0430 \u0431\u044d\u043a\u0435\u043d\u0434 \u0447\u0435\u0440\u0435\u0437 JavaScript. \u0421\u043f\u043e\u0441\u043e\u0431 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442 \u2014 \u0431\u0435\u0440\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u0440\u0438\u0441\u0443\u0435\u043c \u0435\u0435 \u043d\u0430 canvas \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430 \u0431\u044d\u043a\u0435\u043d\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 \u043a\u0430\u043d\u0432\u044b \u0432 base64. \u0422\u0430\u043c \u2014 \u0434\u0435\u0448\u0438\u0444\u0440\u0443\u0435\u043c, \u0447\u0438\u0441\u0442\u0438\u043c \u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u043c \u0432 \u0447\u0438\u0441\u0442\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>  \u0411\u0435\u0437\u043e\u0431\u0440\u0430\u0437\u0438\u0435! \u042d\u0442\u043e\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u043c\u043d\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439. \u0427\u0442\u043e-\u0442\u043e \u0442\u0443\u0442 \u044f\u0432\u043d\u043e \u043d\u0435 \u0442\u0430\u043a, \u043d\u043e \u044f \u0431\u0435\u0433\u0443, \u0443 \u043c\u0435\u043d\u044f \u043d\u0435\u0442\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430\u0437\u0430\u0434 \u0438 \u0442\u0443\u0442 \u0436\u0435 \u0440\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435!<\/p>\n<p>  <\/p>\n<h4>\u042d\u0442\u0430\u043f 2. \u0420\u0435\u0448\u0435\u043d\u0438\u0435<\/h4>\n<p>  \u0410 \u0447\u0442\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0435\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430? \u041f\u043e\u0447\u0435\u043c\u0443 \u0431\u044b \u0438 \u043d\u0435\u0442, \u043f\u043e\u0434\u0443\u043c\u0430\u043b \u044f. \u0411\u044b\u0441\u0442\u0440\u043e \u0443\u0448\u0435\u043b \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e\u043a\u0438 QNetworkAccessManager \u2014 \u0443\u0440\u0430! \u0410 \u0432\u043e\u0442 \u043e\u043d\u043e \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c QWebView, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043c\u044b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u0437\u0430\u0434\u0430\u0435\u043c QWebPage \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0440\u0430\u043d\u0435\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u043c QNetworkAccessManager, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043d\u0430\u0448 \u043a\u043b\u0430\u0441\u0441 \u2014 InterceptorManager (\u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 QNAM).<\/p>\n<p>  \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 InterceptorManager \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0435:<\/p>\n<pre><code>class InterceptorManager : public QNetworkAccessManager {    Q_OBJECT public:    explicit InterceptorManager(QObject *parent = 0);    protected:    QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)    {        QNetworkReply *real = QNetworkAccessManager::createRequest(op, request, outgoingData);        if (request.url().toString().endsWith(&quot;.png&quot;)) {            NetworkReplyProxy *proxy = new NetworkReplyProxy(this, real);            return proxy;        }        return real;    } }; <\/code><\/pre>\n<p>  \u041c\u044b \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c createRequest(), \u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u0443\u044e \u043d\u0430\u043c\u0438 \u043f\u0440\u043e\u043a\u0441\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 QNetworkReply. \u0417\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u043d\u0430\u0434\u043e? QNetworkReply, \u043a\u0430\u043a \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a QIODevice \u043d\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e. \u0422\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u043c \u043d\u0430\u0434\u043e, \u0447\u0442\u043e\u0431\u044b QWebPage \u0442\u0430\u043a\u0438 \u043f\u0440\u043e\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043f\u0440\u043e\u043a\u0441\u0438, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0442\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0438 \u043f\u043e\u0437\u0436\u0435 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u043e\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c QNetworkReply \u2014 \u043d\u0435 \u0441\u0430\u043c\u0430\u044f \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u044f \u043d\u0430\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440:  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">networkreplyproxy.h<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &lt;QApplication&gt;  #include &lt;QWebFrame&gt; #include &lt;QWebPage&gt; #include &lt;QWebView&gt; #include &lt;QWebSettings&gt; #include &lt;QDebug&gt;  #include &lt;QDateTime&gt; #include &lt;QDebug&gt; #include &lt;QFile&gt; #include &lt;QTimer&gt; #include &lt;QNetworkProxy&gt; #include &lt;QNetworkReply&gt; #include &lt;QNetworkCookie&gt;  class NetworkReplyProxy : public QNetworkReply {     Q_OBJECT public:     NetworkReplyProxy(QObject* parent, QNetworkReply* reply)         : QNetworkReply(parent)         , m_reply(reply)     {         \/\/ apply attributes...         setOperation(m_reply-&gt;operation());         setRequest(m_reply-&gt;request());         setUrl(m_reply-&gt;url());          \/\/ handle these to forward         connect(m_reply, SIGNAL(metaDataChanged()), SLOT(applyMetaData()));         connect(m_reply, SIGNAL(readyRead()), SLOT(readInternal()));         connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(errorInternal(QNetworkReply::NetworkError)));          \/\/ forward signals         connect(m_reply, SIGNAL(finished()), SIGNAL(finished()));         connect(m_reply, SIGNAL(uploadProgress(qint64,qint64)), SIGNAL(uploadProgress(qint64,qint64)));         connect(m_reply, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(downloadProgress(qint64,qint64)));          \/\/ for the data proxy...         setOpenMode(ReadOnly);     }      ~NetworkReplyProxy()     {         if (m_reply-&gt;url().scheme() != &quot;data&quot;)             writeDataPrivate();         delete m_reply;     }      \/\/ virtual  methids     void abort() { m_reply-&gt;abort(); }     void close() { m_reply-&gt;close(); }     bool isSequential() const { return m_reply-&gt;isSequential(); }      \/\/ not possible...     void setReadBufferSize(qint64 size) { QNetworkReply::setReadBufferSize(size); m_reply-&gt;setReadBufferSize(size); }      \/\/ ssl magic is not done....     \/\/ isFinished()\/isRunning can not be done *sigh*       \/\/ QIODevice proxy...     virtual qint64 bytesAvailable() const     {         return m_buffer.size() + QIODevice::bytesAvailable();     }      virtual qint64 bytesToWrite() const { return -1; }     virtual bool canReadLine() const { qFatal(&quot;not implemented&quot;); return false; }      virtual bool waitForReadyRead(int) { qFatal(&quot;not implemented&quot;); return false; }     virtual bool waitForBytesWritten(int) { qFatal(&quot;not implemented&quot;); return false; }      virtual qint64 readData(char* data, qint64 maxlen)     {         qint64 size = qMin(maxlen, qint64(m_buffer.size()));         memcpy(data, m_buffer.constData(), size);         m_buffer.remove(0, size);         return size;     }  signals:     void resourceIntercepted(QByteArray);  public Q_SLOTS:     void ignoreSslErrors() { m_reply-&gt;ignoreSslErrors(); }     void applyMetaData() {         QList&lt;QByteArray&gt; headers = m_reply-&gt;rawHeaderList();         foreach(QByteArray header, headers)             setRawHeader(header, m_reply-&gt;rawHeader(header));          setHeader(QNetworkRequest::ContentTypeHeader, m_reply-&gt;header(QNetworkRequest::ContentTypeHeader));         setHeader(QNetworkRequest::ContentLengthHeader, m_reply-&gt;header(QNetworkRequest::ContentLengthHeader));         setHeader(QNetworkRequest::LocationHeader, m_reply-&gt;header(QNetworkRequest::LocationHeader));         setHeader(QNetworkRequest::LastModifiedHeader, m_reply-&gt;header(QNetworkRequest::LastModifiedHeader));         setHeader(QNetworkRequest::SetCookieHeader, m_reply-&gt;header(QNetworkRequest::SetCookieHeader));          setAttribute(QNetworkRequest::HttpStatusCodeAttribute, m_reply-&gt;attribute(QNetworkRequest::HttpStatusCodeAttribute));         setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, m_reply-&gt;attribute(QNetworkRequest::HttpReasonPhraseAttribute));         setAttribute(QNetworkRequest::RedirectionTargetAttribute, m_reply-&gt;attribute(QNetworkRequest::RedirectionTargetAttribute));         setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, m_reply-&gt;attribute(QNetworkRequest::ConnectionEncryptedAttribute));         setAttribute(QNetworkRequest::CacheLoadControlAttribute, m_reply-&gt;attribute(QNetworkRequest::CacheLoadControlAttribute));         setAttribute(QNetworkRequest::CacheSaveControlAttribute, m_reply-&gt;attribute(QNetworkRequest::CacheSaveControlAttribute));         setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, m_reply-&gt;attribute(QNetworkRequest::SourceIsFromCacheAttribute));         setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, m_reply-&gt;attribute(QNetworkRequest::DoNotBufferUploadDataAttribute));         emit metaDataChanged();     }     void errorInternal(QNetworkReply::NetworkError _error)     {         setError(_error, errorString());         emit error(_error);     }     void readInternal()     {         QByteArray data = m_reply-&gt;readAll();         m_data += data;         m_buffer += data;         emit readyRead();     }  protected:     void writeDataPrivate()     {         QByteArray httpHeader;         QList&lt;QByteArray&gt; headers = rawHeaderList();         foreach(QByteArray header, headers) {             if (header.toLower() == &quot;content-encoding&quot;                 || header.toLower() == &quot;transfer-encoding&quot;                 || header.toLower() == &quot;content-length&quot;                 || header.toLower() == &quot;connection&quot;)                 continue;              \/\/ special case for cookies.... we need to generate separate lines             \/\/ QNetworkCookie::toRawForm is a bit broken and we have to do this             \/\/ ourselves... some simple heuristic here..             if (header.toLower() == &quot;set-cookie&quot;) {                 QList&lt;QNetworkCookie&gt; cookies = QNetworkCookie::parseCookies(rawHeader(header));                 foreach (QNetworkCookie cookie, cookies) {                     httpHeader += &quot;set-cookie: &quot; + cookie.toRawForm() + &quot;\\r\\n&quot;;                 }             } else {                 httpHeader += header + &quot;: &quot; + rawHeader(header) + &quot;\\r\\n&quot;;             }         }         httpHeader += &quot;content-length: &quot; + QByteArray::number(m_data.size()) + &quot;\\r\\n&quot;;         httpHeader += &quot;\\r\\n&quot;;          if(m_reply-&gt;error() != QNetworkReply::NoError) {             qWarning() &lt;&lt; &quot;\\tError with: &quot; &lt;&lt; this &lt;&lt; url() &lt;&lt; error();             return;         }          const QByteArray origUrl = m_reply-&gt;url().toEncoded();         const QByteArray strippedUrl = m_reply-&gt;url().toEncoded(QUrl::RemoveFragment | QUrl::RemoveQuery);         interceptResource(origUrl, m_data, httpHeader, operation(), attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt());     }      void interceptResource(const QByteArray& url, const QByteArray& data, const QByteArray& header, int operation, int response)     {         Q_UNUSED(header);         Q_UNUSED(url);         Q_UNUSED(operation);         Q_UNUSED(response);          emit resourceIntercepted(data);     }  private:     QNetworkReply* m_reply;     QByteArray m_data;     QByteArray m_buffer; }; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0421\u0440\u0430\u0437\u0443 \u0433\u043e\u0432\u043e\u0440\u044e, \u0447\u0442\u043e \u043e\u0441\u043e\u0431\u043e \u043d\u0435 \u043c\u043e\u0433\u0443 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0437\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a, \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435, \u043d\u043e \u044d\u0442\u0430 \u0448\u0442\u0443\u043a\u043e\u0432\u0438\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0430 \u044d\u0442\u043e \u2014 \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435. \u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u043a\u0441\u0438 \u043b\u0435\u0436\u0438\u0442 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430 \u0432\u0430\u0448\u0438\u0445 \u043f\u043b\u0435\u0447\u0430\u0445.<\/p>\n<h4>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h4>\n<p>  \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u0432\u0441\u0435 \u044d\u0442\u043e \u0434\u043e\u0431\u0440\u043e \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u0430\u0434\u0435\u044e\u0441\u044c \u044d\u0442\u043e \u0447\u0435\u043c-\u0442\u043e \u043a\u043e\u043c\u0443-\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442.<\/p>\n<p>  \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435,<br \/>  namespace  \t\t\t\t<\/p>\n<div class=\"polling\">\n<form action=\"\/json\/polling\/\" class=\"poll\" method=\"post\">\n<div class=\"poll_title\">\u0421\u0442\u043e\u0438\u0442 \u043b\u0438 \u0434\u043e\u0432\u0435\u0441\u0442\u0438 proxy \u0434\u043e \u0443\u043c\u0430 \u0438 \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 \u043d\u0430 GitHub<\/div>\n<p>  \t\t<input type=\"hidden\" name=\"post_id\" value=\"191476\"\/> \t\t<input type=\"hidden\" name=\"polling_question_id\" value=\"8794\"\/>  \t\t<\/p>\n<table class=\"answer\">\n<tr>\n<td class=\"input\"> \t\t\t\t\t<input type=\"radio\" id=\"vv44994\" \t\t\t\t\t\tclass=\"radio js-field-data\" \t\t\t\t\t\tname=\"variant[]\" \t\t\t\t\t\tvalue=\"44994\" \/> \t\t\t\t<\/td>\n<td class=\"label\"> \t\t\t\t\t<label for=\"vv44994\">\u0414\u0430<\/label> \t\t\t\t<\/td>\n<\/tr>\n<tr>\n<td class=\"input\"> \t\t\t\t\t<input type=\"radio\" id=\"vv44996\" \t\t\t\t\t\tclass=\"radio js-field-data\" \t\t\t\t\t\tname=\"variant[]\" \t\t\t\t\t\tvalue=\"44996\" \/> \t\t\t\t<\/td>\n<td class=\"label\"> \t\t\t\t\t<label for=\"vv44996\">\u041d\u0435\u0442<\/label> \t\t\t\t<\/td>\n<\/tr>\n<\/table>\n<p class=\"for_users_only_msg\">\u0422\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u0443\u0442 \u0443\u0447\u0430\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043e\u043f\u0440\u043e\u0441\u0435. <a href=\"https:\/\/auth.habrahabr.ru\/login\/\">\u0412\u043e\u0439\u0434\u0438\u0442\u0435<\/a>, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430.<\/p>\n<p class=\"total\">\u041d\u0438\u043a\u0442\u043e \u0435\u0449\u0451 \u043d\u0435 \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u043b. \u0412\u043e\u0437\u0434\u0435\u0440\u0436\u0430\u0432\u0448\u0438\u0445\u0441\u044f \u043d\u0435\u0442.<\/p>\n<\/p><\/form>\n<\/p><\/div>\n<div class=\"clear\"><\/div>\n<\/p><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/191476\/\"> http:\/\/habrahabr.ru\/post\/191476\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"content html_format\">\n<pre><code>Habrahabr::Instance()-&gt;hello(); <\/code><\/pre>\n<p>  \u042f \u0434\u0430\u0432\u043d\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0438\u0441\u0430\u043b \u043d\u0430 \u0445\u0430\u0431\u0440, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u0430\u0432\u043d\u043e. \u041d\u043e \u043d\u0430 \u043f\u0440\u043e\u0448\u0435\u0434\u0448\u0435\u0439 \u043d\u0435\u0434\u0435\u043b\u0435 \u044f \u0438\u0437\u0440\u044f\u0434\u043d\u043e \u043f\u043e\u0442**\u0445\u0430\u043b\u0441\u044f \u0441 \u043c\u043e\u0434\u0443\u043b\u0435\u043c QtWebkit 5.1 \u0438 \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u0438\u043c \u0442\u043e\u043d\u043e\u043c \u0431\u044b\u043b\u043e \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u0430\u043c \u043a\u0430\u043a\u043e\u0439 \u043c\u0440\u0430\u043a \u0436\u0434\u0435\u0442 \u0432\u0430\u0441 \u0442\u0430\u043c, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u0445\u0432\u0430\u0442\u0438\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u044d\u043a\u0440\u0430\u043d\u0430 \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u0440\u043e\u0434\u0435.<\/p>\n<p>  \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u043c\u043e\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u043b\u0435\u0436\u0430\u043b\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0440\u0430\u0443\u0437\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0432\u0441\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u0431\u0440\u0430\u0443\u0437\u0438\u0442. \u042d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434: \u043f\u043e\u0432\u0435\u0441\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0435 QWebElement \u043f\u043e \u0441\u0435\u043b\u0435\u043a\u0442\u043e\u0440\u0443 \u201cimg\u201d \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u0438\u0445 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u0435 (QWebElement::render()) \u0447\u0435\u0440\u0435\u0437 QPainter \u043d\u0430 QImage, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b.<\/p>\n<p>  \u041d\u043e \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043d\u0435 \u0432\u0441\u0435 \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e. \u041f\u0440\u043e \u0442\u043e\u0442 \u043f\u0443\u0442\u044c \u0441\u0430\u043c\u0443\u0440\u0430\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438\u0437\u043b\u043e\u0436\u0435\u043d \u043c\u043d\u043e\u0439 \u043f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430. \u041f\u0440\u0438\u044f\u0442\u043d\u043e\u0433\u043e \u0430\u043f\u043f\u0435\u0442\u0438\u0442\u0430!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-191476","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/191476","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=191476"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/191476\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=191476"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=191476"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=191476"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}