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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: QPixmapCache пропадает содержимое  (Прочитано 12189 раз)
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« : Май 07, 2013, 08:17 »

Установил предел кэша в 20Мб. На экран вывожу картинку состоящую из фрагментов 50 раз в секунду, фрагменты читаю из кэша(find), если его нет в кеше вывожу пустую картинку затем медленно читаю с диска и загружаю в кэш. Ровно через каждые 30 секунд первое изображение пропадает и заново загружается с диска.
Можно ли отучить QPixmapCache терять содержимое?
Если нельзя, то посоветуйте наиболее красивый способ, для реализации хранилища картинок при переполнении которого удаляются первые занесенные в него элементы.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #1 : Май 07, 2013, 08:47 »

Показывай код.
Записан

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

Сообщений: 600



Просмотр профиля
« Ответ #2 : Май 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
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #3 : Май 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 файлов он постоянно стирает только первый.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #4 : Май 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 )
 
На твою сигнатуру не похоже.
Записан

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

Сообщений: 600



Просмотр профиля
« Ответ #5 : Май 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
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #6 : Май 07, 2013, 10:45 »

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

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

Сообщений: 600



Просмотр профиля
« Ответ #7 : Май 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"); - соответственно если файл уже загружен, то загрузить из кэша.
« Последнее редактирование: Май 07, 2013, 11:11 от deMax » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #8 : Май 07, 2013, 11:15 »

Да, с размером это я обсчитался.
Записан

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

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #9 : Май 07, 2013, 11:15 »

Приложи сюда минимальный компилябельный пример.
Записан

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

Сообщений: 600



Просмотр профиля
« Ответ #10 : Май 07, 2013, 11:25 »

http://rghost.ru/45821907
Картинка первая попавшаяся.
Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


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


Просмотр профиля WWW
« Ответ #11 : Май 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
Записан

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

Сообщений: 600



Просмотр профиля
« Ответ #12 : Май 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 выполнил недопустимую операцию.
« Последнее редактирование: Май 07, 2013, 11:53 от deMax » Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #13 : Май 08, 2013, 07:35 »

Итого: В версии 4.8.4 и 4.8.1 под windows баг есть, в 4.7.4 нет.
Записан
deMax
Хакер
*****
Offline Offline

Сообщений: 600



Просмотр профиля
« Ответ #14 : Май 17, 2013, 10:38 »

В версии 4.7.4 баг все же присутствует, хоть helloworld вроде и работает, но на моем ПО видно мерцание картинки раз в полминуты(картинки загружаются параллельно и когда кэш ее теряет она пропадает).

Если есть возможность проверьте под OS Windows версия Qt 4.8.1 или 4.8.4. Может у меня в системе что то неправильно стоит или луна не в той фазе чтобы QPixmap работал.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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