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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: А как просто картинку загрузить? [SOLVED]  (Прочитано 7458 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Апрель 14, 2011, 15:31 »

Есть прямой урл картинки формата JPG. Надо ее получить в QImage. И что-то не очень видно, как это сделать.

Код:
QImgage pic( URL );

работать не должно, поскольку URL - не имя файла.

Загружать всю страницу и разбирать ее содержимое через DOM не годится, программа получает прямые ссылки на картинки, которые надо слизать.

« Последнее редактирование: Апрель 18, 2011, 22:14 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #1 : Апрель 14, 2011, 15:35 »

Скачай и loadFromData
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Апрель 14, 2011, 15:41 »

Цитировать
Скачай

Как? В WebKit есть простой способ это сделать?
« Последнее редактирование: Апрель 14, 2011, 15:44 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Апрель 14, 2011, 15:42 »

QNetworkAccessManager
Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #4 : Апрель 14, 2011, 15:48 »

а более высокого уровня в WebKit нет средств?
Записан

2^7-1 == 127, задумайтесь...
Fess
Гость
« Ответ #5 : Апрель 15, 2011, 06:48 »

У вас же есть урл нужного изображения, вот и качайте его простым get-ом.
Ничего более сложного здесь не нужно. Можете даже не сохранять, а сразу создавать QImage/QPixmap из потока данных.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Апрель 15, 2011, 12:52 »

хотелось что-нибудь типа

QImage pic = getWebImage( "http://сервер.там/image.jpg" );

если есть где-то готовое getWebImage(), но очевидно нет, значит придется самому написать, вместо одной строки будет лишние два десятка

тем более, что WebKit в статике не собирается, начиная с 4.7.0 его поддержка для статической сборки отменена  Обеспокоенный
Записан

2^7-1 == 127, задумайтесь...
Sancho_s_rancho
Гость
« Ответ #7 : Апрель 15, 2011, 13:06 »

QNetworkAccessManager

QNetworkAccessManager

QNetworkAccessManager

QNetworkAccessManager

ыыыыыыыыыыы
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #8 : Апрель 17, 2011, 20:27 »

переделал на использование QNetworkAccessManager, тем более, что с WebKit в статике не собирается

но манагер работает асинхронно, а мне надо по очереди грузить и обрабатывать изображения, и что-то никак не вижу, как корректно сделать ожидание загрузки каждой следующей картинки, цикл крутится, открывает кучу соединений, стремительно пожирает память, а слот обработки окончания загрузки самой первой картинки так и не запускается

хотя он правильно привязан, проверял на одной картинке - она грузится, слот вызывается, обрабатывает

тупо флаг взводить в обработчике завершения загрузки картинки - не правильно, будет процессор пожираться, да и не работает, кстати...

есть способ сделать сетевые операции синхронными, чтобы get() возвращался только когда обработчик завершения и все остальные отработают?
« Последнее редактирование: Апрель 17, 2011, 20:29 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #9 : Апрель 18, 2011, 00:24 »

не, блин, мозги сломал... уже и с семафорами пробовал - бестолку

наверно дело в том, что прорисовку картинок решил вставить в перегруженный метод paintEvent()

Код:
void MainWindow::paintEvent( QPaintEvent * event )
{
    if( firstpaint )
    {
        listmanager->get( QNetworkRequest( QUrl( "http://........" ) ) );
        firstpaint = false;
    }
}

более подходящего места что-то не вижу, может кто подскажет? всадил туда, поскольку картинки надо показывать в окне, то есть, отрисовывать, и вроде как paintEvetn для этого подходящее место, но возможно нет

когда загружен список картинок с помощью listmanager, метод его обработки вызывается

Код:
void MainWindow::finishedList( QNetworkReply * reply )
{
    if( reply->error() == QNetworkReply::NoError )
    {
        forever
        {
            QByteArray byteline = reply->readLine();
            if( byteline.size() == 0 )
                break;
            urllist << byteline; // urllist это QStringList
        }
        foreach( QString url, urllist )
            imgmanager->get( QNetworkRequest( url ) ) );
    }
    else
        networkerror = true;
    reply->deleteLater();
}

и вот после этого косяк, запросы с адресами из urllist явно набиваются в очередь вызовами imgmanager->get(), и пока они не закончат набиваться, ни один из запросов не завершается, и только когда они все набились, все это завершилось, только тогда начинает стрелять вызовами void MainWindow::finishedImg( QNetworkReply * reply ), где собственно картинки рисуются в окне с помощью QLabel, и там же обрабатываются

такое не годится, мне надо картинки обрабатывать последовательно, одну за другой, их могут быть десятки тысяч

можно как-то пропихивать эту очередь в QNetworkAccessManager()?
« Последнее редактирование: Апрель 18, 2011, 01:16 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #10 : Апрель 18, 2011, 22:13 »

все, победил - оказалось, что хотя QNetWorkManager и асинхронный, но при вызове его из обработчиков событий он корректно не работает

при вызове из отдельных тредов или слотов обработки сигналов таймера работает нормально
Записан

2^7-1 == 127, задумайтесь...
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #11 : Апрель 19, 2011, 10:02 »

Цитировать
более подходящего места что-то не вижу, может кто подскажет?
Хм, пожалуй, это самое неподходящее место.
MainWindow::paintEvent() - будет вызван только после ресайза или update(). Причём асинхронно.

Если хотите грузить картинки синхронно, то нужно заряжать QEventLoop:
Код
C++ (Qt)
#include <QImage>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkProxy>
 
class UrlImage : public QObject, public QImage, public QNetworkRequest
{
Q_OBJECT
public:
UrlImage( const QString& url, QObject* parent = 0 )
: QObject( parent )
, QNetworkRequest( url )
{
QNetworkAccessManager am;
// am.setProxy( QNetworkProxy( QNetworkProxy::HttpProxy, host, port ) );
 
QNetworkReply* reply = am.get( *this );
connect( reply, SIGNAL(finished()), this, SLOT(requestFinished()) );
 
QEventLoop loop;
connect( reply, SIGNAL(finished()), &loop, SLOT(quit()) );
connect( reply, SIGNAL(error(QNetworkReply::NetworkError)), &loop, SLOT(quit()) );
loop.exec();
}
 
private:
UrlImage( const UrlImage& ) {}
 
protected slots:
void requestFinished()
{
QNetworkReply* reply = qobject_cast< QNetworkReply* >( sender() );
QString path( reply->url().path() );
QString suffix( path.mid( path.lastIndexOf( '.' ) + 1 ) );
 
QImage::load( reply, suffix.toLatin1().constData() );
 
reply->deleteLater();
}
};
 
Записан

Qt 5.11/4.8.7 (X11/Win)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #12 : Апрель 23, 2011, 20:36 »

Цитировать
MainWindow::paintEvent() - будет вызван только после ресайза или update().

ничего подобного, он всегда вызывается при первой отрисовке окна, поэтому внутри него

Код:
if( firstpaint )
{
     firstpaint = false;
     .....
}

вполне съедобно, но не в том случае, если требуется работа с сетью, что к сожалению, нигде не документировано
Записан

2^7-1 == 127, задумайтесь...
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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