Russian Qt Forum
Ноябрь 24, 2024, 03:57 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Собственный QNetworkReply :( не могу разобраться помогите....  (Прочитано 5296 раз)
knaklezz
Гость
« : Февраль 28, 2010, 18:14 »

Привет кьют начал изучать недавно, и попал в тупик Грустный

Собственно использую QWebKit для вывода сгенерированного программой html текста, весь контент для странички содержится в zip архивах поэтому использую ссылки вида: <img src="zip://pack_12.zip/1.jpg">, т.е мне надо реализовать обработчик для таких ссылок, я переопределил

QNetworkAccessManager.createRequest (Operation, QNetworkRequest, QIODevice device = None)

Создал свой

class MyNetworkReply : public QNetworkReply

переопределил в нем все виртуальные методы от QIODevice и QNetworkReply.

Устанавливаю Header Для картинки (image/jpeg), url (zip://pack_12.zip/1.jpg), QNetworkRequest.

Возвращаю экземпляр из функции QNetworkAccessManager.createRequest.

В итоге QWebKit не чего не загружает, единственную функцию которую вызывает QWebKit  это QNetworkReply::url().


Кто нибуть переопределял класс QNetworkReply на свой, поделитесь опытом пожалуйста.


http://doc.trolltech.com/qq/32/qq32-webkit-protocols.html  -  читал, я понял что надо посылать readyRead() сигнал, но как узнать что QWebPage уже приконнектился к сигналу readyRead().
Записан
SABROG
Гость
« Ответ #1 : Февраль 28, 2010, 20:45 »

Думаю будет справедливо, если ты выложишь свои наработки, которые можно собрать и посмотреть чего ты забыл добавить или сделал не так. Вопрос не из разряда простых, тут телепаты нужны с третьим глазом, которые смогут на расстоянии в твои исходники посмотреть.
Записан
knaklezz
Гость
« Ответ #2 : Март 01, 2010, 00:45 »

Получилось Улыбающийся использовал QThread посмотрите правильно ли реализовал, или еще есть более оптимальные варианты Улыбающийся

MyNetworkReply.h

Код:
#pragma once

#include <QtNetwork/QNetworkReply>
#include <QtCore/QFile>
#include <QtCore/QByteArray>

#include <QtCore/QThread>

class MyNetworkReply : public QNetworkReply, QThread
{
private:
QFile* m_file;
QByteArray m_content;
qint64 m_offset;
public:
MyNetworkReply(QObject* parent = 0);
~MyNetworkReply();
//QNetworkReply
public:
void abort();
void setConfig(const QUrl&, QNetworkAccessManager::Operation, const QNetworkRequest&);
//QIODevice
public:
void run();
qint64 bytesAvailable() const;
bool isSequential() const;
bool open(OpenMode open);
protected:
qint64 readData(char* data, qint64 maxSize);
};

MyNetworkReply.cpp

Код:
#include "MyNetworkReply.h"

MyNetworkReply::MyNetworkReply(QObject* parent) : QNetworkReply(parent), QThread()
{
m_file = new QFile("1.jpg");

this->open(QIODevice::ReadOnly | QIODevice::Unbuffered);

m_offset = 0;

m_content = m_file->readAll();

this->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));

this->setHeader(QNetworkRequest::ContentLengthHeader, QVariant(m_content.size()));

this->start();
}

MyNetworkReply::~MyNetworkReply()
{
this->close();

delete m_file;
}

void MyNetworkReply::abort()
{
this->close();
}

void MyNetworkReply::setConfig(const QUrl& turl, QNetworkAccessManager::Operation op, const QNetworkRequest& req)
{
this->setUrl(turl);
this->setOperation(op);
this->setRequest(req);
}

qint64 MyNetworkReply::readData(char* data, qint64 maxSize)
{
    if (m_offset < m_content.size())
{
        qint64 number = qMin(maxSize, m_content.size() - m_offset);

        memcpy(data, m_content.constData() + m_offset, number);

        m_offset += number;

        return number;
    }
else
{
        return -1;
}
}

qint64 MyNetworkReply::bytesAvailable() const
{
return m_content.size() - m_offset;
}

bool MyNetworkReply::isSequential() const
{
return true;
}

bool MyNetworkReply::open(OpenMode open)
{
QIODevice::setOpenMode(open);

return m_file->open(open);
}

void MyNetworkReply::run()
{
while(m_offset == 0)
{
emit QNetworkReply::readyRead();
emit QNetworkReply::finished();
}
}

MyNetworkAccessManager.h

Код:
#pragma once

#include <QtNetwork/QNetworkAccessManager>

class MyNetworkAccessManager : public QNetworkAccessManager
{
private:
QNetworkReply* createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData = 0);
public:
MyNetworkAccessManager();
~MyNetworkAccessManager();
};

MyNetworkAccessManager.cpp

Код:
#include "MyNetworkAccessManager.h"

#include "MyNetworkReply.h"

MyNetworkAccessManager::MyNetworkAccessManager() : QNetworkAccessManager()
{
}

MyNetworkAccessManager::~MyNetworkAccessManager()
{
}

QNetworkReply* MyNetworkAccessManager::createRequest(Operation op, const QNetworkRequest& req, QIODevice* outgoingData)
{
MyNetworkReply* networkReply = new MyNetworkReply(this);

networkReply->setConfig(req.url(), op, req);

return networkReply;
}

main.cpp

Код:
#include <windows.h>

#include <QtGui/QApplication>
#include <QtWebKit/QWebView>

#include "MyNetworkAccessManager.h"
#include "MyNetworkReply.h"

#pragma comment (lib, "QtGui4.lib")
#pragma comment (lib, "QtCore4.lib")
#pragma comment (lib, "qtmain.lib")
#pragma comment (lib, "QtNetwork4.lib")
#pragma comment (lib, "QtWebKit4.lib")


int main(int argc, char* argv[])
{
QApplication app(argc, argv);

QWebView* webView = new QWebView();

webView->page()->setNetworkAccessManager(new MyNetworkAccessManager());

webView->page()->setForwardUnsupportedContent(true);

QWidget::connect(webView->page(), SIGNAL(unsupportedContent(QNetworkReply*)), &app, SLOT(aboutQt()));

webView->setHtml("<b>Image:</b><br><img border=\'1\' src=\'files/1.jpg\'>", QUrl("test://test.ru/"));

webView->show();

return app.exec();
}
Записан
victor_yacovlev
Гость
« Ответ #3 : Март 09, 2011, 22:32 »

Мне удалось сделать это без QThread:
Код
C++ (Qt)
struct MiniServerResponse
{
   QString mimeType;
   QByteArray data;
   int code;
   QString errorText;
};
 
class MiniServerNetworkReply
       : public QNetworkReply
 
{
public:
   explicit MiniServerNetworkReply(const MiniServerResponse &response, QObject * parent = 0);
   ~MiniServerNetworkReply();
   inline qint64 bytesAvailable() const { return data.size() - position; }
   inline bool isSequential() const { return true; }
   inline void abort() { }
protected:
   qint64 readData(char *data, qint64 maxlen);
   qint64 position;
private:
   QByteArray data;
   QString contentType;
};
 
 
qint64 MiniServerNetworkReply::readData(char *buffer, qint64 maxlen)
{
   qint64 cnt = qMin(maxlen, bytesAvailable());
   const char * slice = data.mid(position, cnt).data();
   qstrncpy(buffer, slice, cnt);
   return cnt;
}
 
 
 
MiniServerNetworkReply::MiniServerNetworkReply(const MiniServerResponse &response, QObject * parent)
   : QNetworkReply(parent)
{
   QNetworkReply::open(QIODevice::ReadOnly);
   position = 0;
   contentType = response.mimeType;
   if (response.code==200) {
       // HTTP 200 is OK
       data = response.data;
   }
   else {
       QString error = QString("<html><head><title>Error %1</title></head><body><h1>Error %1</h1><p>%2</p></body></html>")
               .arg(response.code)
               .arg(response.errorText);
       data = error.toUtf8();
   }
   setHeader(QNetworkRequest::LastModifiedHeader, QDateTime::currentDateTime());
   setHeader(QNetworkRequest::ContentLengthHeader, data.size());
   setHeader(QNetworkRequest::ContentTypeHeader, response.mimeType);
   QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
   QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection,
                             Q_ARG(qint64, data.size()), Q_ARG(qint64, data.size()));
   QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
   QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
}
 
Записан
BRE
Гость
« Ответ #4 : Март 09, 2011, 22:40 »

Ну нельзя так делать:
Код
C++ (Qt)
qint64 MiniServerNetworkReply::readData(char *buffer, qint64 maxlen)
{
   ...
   const char * slice = data.mid(position, cnt).data();
   // Здесь slice указывает на уже разрушенный буфер (то что это работает - случайность, может и не работать или работать не так. :)
}
 
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.164 секунд. Запросов: 20.