Russian Qt Forum

Qt => Мультимедиа => Тема начата: deMax от Май 07, 2013, 08:17



Название: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 08:17
Установил предел кэша в 20Мб. На экран вывожу картинку состоящую из фрагментов 50 раз в секунду, фрагменты читаю из кэша(find), если его нет в кеше вывожу пустую картинку затем медленно читаю с диска и загружаю в кэш. Ровно через каждые 30 секунд первое изображение пропадает и заново загружается с диска.
Можно ли отучить QPixmapCache терять содержимое?
Если нельзя, то посоветуйте наиболее красивый способ, для реализации хранилища картинок при переполнении которого удаляются первые занесенные в него элементы.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Пантер от Май 07, 2013, 08:47
Показывай код.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 09:50
Написал Helloworld, запустил и все красиво работает, однако когда прервал процесс в консоли появилось следующее:
QTime("10:41:11") QSize(2000, 1000)
QTime("10:42:11") QSize(2000, 1000)
QTime("10:42:51") QSize(2000, 1000)
QTime("10:43:31") QSize(2000, 1000)
QTime("10:44:11") QSize(2000, 1000)
QTime("10:44:51") QSize(2000, 1000)
QTime("10:45:31") QSize(2000, 1000)
QTime("10:46:11") QSize(2000, 1000)
Программа неожиданно завершилась.
D:\WORK\learn\debug\learn.exe завершился с кодом 62097

main.cpp:

Код:
#include <QApplication>
#include <QPixmapCache>
#include "zzz.h"

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

    QPixmapCache::setCacheLimit(20*1024);
    QTimer *t = new QTimer;
    t->start(10);
    ZZZ *a = new ZZZ;
    QObject::connect(t,SIGNAL(timeout()),a,SLOT(timer()));

    return app.exec();
}
zzz.h
Код:
#ifndef ZZZ_H
#define ZZZ_H

#include <QtGui>

class ZZZ: public QObject
{
    Q_OBJECT
public:
    ZZZ();
public slots:
    void timer()
    {
        QPixmap *pm = QPixmapCache::find("1");
        if(!pm) {
            QPixmapCache::insert("1",QPixmap("1.jpg"));
            qDebug()<<QTime::currentTime()<<QPixmapCache::find("1")->size();
        }
    }
};

#endif // ZZZ_H


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 10:00
Qt Creator 2.4.1 (Основан на Qt 4.7.4 (32-х битной)). Qt 4.8.1 ставился из qt_sdk_1_2_1 под виндовс 7.

Это содержимое консоли:
Цитировать
Запускается D:\WORK\learn\debug\learn.exe...
QTime("10:55:15") QSize(2000, 1000)
QTime("10:56:15") QSize(2000, 1000)
QTime("10:56:55") QSize(2000, 1000)
QTime("10:57:35") QSize(2000, 1000)
QTime("10:58:16") QSize(2000, 1000)

файл zzz.cpp
Код:
#include "zzz.h"

ZZZ::ZZZ()
{
}

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


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Пантер от Май 07, 2013, 10:08
http://qt-project.org/doc/qt-4.8/qpixmapcache.html
Код
C++ (Qt)
bool find ( const QString & key, QPixmap * pixmap )
bool find ( const Key & key, QPixmap * pixmap )
 
На твою сигнатуру не похоже.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 10:33
Цитировать
На твою сигнатуру не похоже.
http://harmattan-dev.nokia.com/docs/library/html/qt4/qpixmapcache-obsolete.html
Цитировать
The following class members are obsolete. They are provided to keep old source code working. We strongly advise against using them in new code.
Static Public Members
bool    find ( const QString & key, QPixmap & pixmap ) (obsolete)
QPixmap *    find ( const QString & key ) (obsolete)

Метод "bool   find ( const Key & key, QPixmap * pixmap )" меня не устраивает тем что ему нужно еще и объект создать в который он скопирует из кеша изображение. С другой стороны я не смогу попортить изображения в кеше, но я особо и не собирался.

для теста я все же переделал слот timer
Код:
    void timer()
    {
//        qDebug()<<QTime::currentTime()<<"zzz";
        QPixmap pm;
        if(!QPixmapCache::find("1",&pm)) {
            QPixmapCache::insert("1",QPixmap("1.jpg"));

            QPixmapCache::find("1",&pm);
            qDebug()<<QTime::currentTime()<<pm.size();
        }
результат:
Цитировать
Запускается D:\WORK\learn\debug\learn.exe...
QTime("11:31:58") QSize(2000, 1000)
QTime("11:32:58") QSize(2000, 1000)
Программа неожиданно завершилась.
D:\WORK\learn\debug\learn.exe завершился с кодом 62097


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Пантер от Май 07, 2013, 10:45
1. Написано же, этот статический метод оставлен только для старого кода и нельзя его юзать.
2. А стектрейс куда показывает при падении?
3. У тебя кэшлимит меньше изображения.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 11:01
>>1. Написано же, этот статический метод оставлен только для старого кода и нельзя его юзать.
Я так и понял. Придется удалить класс, ибо мне такой функционал не нужен. Тем не менее все же хочется понять что это баг или фича?

>>2. А стектрейс куда показывает при падении?
Извиняюсь за вывод консоли, но неожиданное завершение программы вызвано нажатием на красный квадратик(завершение выполнения). К багу/фиче отношения не имеет.

>>3. У тебя кэшлимит меньше изображения.
Код:
QPixmapCache::setCacheLimit(20*1024);
20 метров для картинки в 334 килобайта? даже в несжатом виде с альфаканалом она весит 2000*1000*4бита = ~8метров.
но все же, поставил кеш на 50 метров:
Цитировать
Запускается D:\WORK\learn\debug\learn.exe...
QTime("11:59:14") QSize(2000, 1000)
QTime("12:00:15") QSize(2000, 1000)
QTime("12:00:55") QSize(2000, 1000)
QTime("12:01:35") QSize(2000, 1000)

p.s. Мне кажется этот класс был бы удобным в такой реализации:
QPixmap pix = QPixmapCache::open("./1.jpg"); - соответственно если файл уже загружен, то загрузить из кэша.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Пантер от Май 07, 2013, 11:15
Да, с размером это я обсчитался.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Пантер от Май 07, 2013, 11:15
Приложи сюда минимальный компилябельный пример.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 11:25
http://rghost.ru/45821907
Картинка первая попавшаяся.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Пантер от Май 07, 2013, 11:31
Раскомментил 14 строку, получил вот такой вывод:
Код:
QTime("12:29:10") zzz 
QTime("12:29:10") QSize(2000, 1000)
QTime("12:29:10") zzz
QTime("12:29:10") zzz
QTime("12:29:11") zzz
QTime("12:29:11") zzz
Все работает.
Qt: 4.8.4
OS: Linux


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 07, 2013, 11:50
Итого: в версии 4.8.1 под windows есть мифический баг, в результате которого qpixmapcache начинает сам очищать себя.

Под линуксом еще не проверял(тоже qt 4.8.4 стоит в системе), но вот если поставить профиль Qt 4.7.4 for Desktop - mingw4.4. То программа работает, за пару минут ничего не теряет(запущу прогу на обед и посмотрю не потеряет ли кеш за пол часа).

offtop: Под какой сборкой qt лучше собирать проект чтобы поменьше сюрпризов ловить(на 5-ку пока не хочу переходить)? У меня версия 4.8.4 и криатор 2.7.0 при запуске в режиме отладки всплывает окно о том что gdb выполнил недопустимую операцию.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 08, 2013, 07:35
Итого: В версии 4.8.4 и 4.8.1 под windows баг есть, в 4.7.4 нет.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 17, 2013, 10:38
В версии 4.7.4 баг все же присутствует, хоть helloworld вроде и работает, но на моем ПО видно мерцание картинки раз в полминуты(картинки загружаются параллельно и когда кэш ее теряет она пропадает).

Если есть возможность проверьте под OS Windows версия Qt 4.8.1 или 4.8.4. Может у меня в системе что то неправильно стоит или луна не в той фазе чтобы QPixmap работал.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 29, 2013, 14:18
Есть ли аналоги или собственная реализация?

p.s. Как считать размер QPixmap в памяти?


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Igors от Май 29, 2013, 16:29
p.s. Как считать размер QPixmap в памяти?
width() * height() * 4


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Old от Май 29, 2013, 17:05
p.s. Как считать размер QPixmap в памяти?
Не нужно его считать. Pixmap может вообще не храниться в оперативной памяти, по крайней мере твоего процесса.


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Май 31, 2013, 15:48
Как работает QPixmap?

Решил хранить картинки так: QList<QPair, *QPixmap> > но памяти пожирает очень много в отличие от QPixmapCache, можно ли хранить PNG в памяти?


Название: Re: QPixmapCache пропадает содержимое
Отправлено: Kurles от Июнь 01, 2013, 11:48
Как работает QPixmap?

Решил хранить картинки так: QList<QPair, *QPixmap> > но памяти пожирает очень много в отличие от QPixmapCache, можно ли хранить PNG в памяти?
Почему нельзя - можно. QList<QPair, *QByteArray>


Название: Re: QPixmapCache пропадает содержимое
Отправлено: panAlexey от Июнь 02, 2013, 15:15
Как работает QPixmap?

Решил хранить картинки так: QList<QPair, *QPixmap> > но памяти пожирает очень много в отличие от QPixmapCache, можно ли хранить PNG в памяти?
Почему нельзя - можно. QList<QPair, *QByteArray>
при таком сохранении есть баги. при выводе на печать воспринимает пиксмап восстановленный из байт эрея как негатив.
т.е. если загоняешь белый квадрат с черной надписью на печать выгоняет черный квадрат с белой надписью )))))
рел. 4.7.2 - точно


Название: Re: QPixmapCache пропадает содержимое
Отправлено: deMax от Июнь 03, 2013, 15:41
А если хранить в памяти png, какая будет нагрузка на проц если мне постоянно потребуется их отрисовка на экране(не все а маленькая часть, которая находится в области отображения).