crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Qt::DecorationRole и УТЕЧКА ПАМЯТИ, Возможно это БАГ. Давайте подумаем вместе.
Iron Lappu
  опции профиля:
сообщение 8.5.2011, 21:18
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 30.3.2011
Пользователь №: 2558

Спасибо сказали: 0 раз(а)




Репутация:   0  


Приветствую Вас, уважаемые!

Привожу пример кода, который точно повторяет проблему:

QVariant QMyModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    QVariant data;
    switch (role)
    {
    case Qt::EditRole:
    case Qt::DisplayRole:
        {
            data = QVariant("text");
            break;
        }
    case Qt::DecorationRole:
        {
            QPixmap pixmap(16, 16);
            pixmap.fill(QColor(255, 0, 0));
            data = QVariant::fromValue(pixmap);
            break;
        }
    default:
        {
            data = QVariant();
            break;
        }
    }
    return data;
}


Если при таком раскладе попытаться отредактировать какой-либо элемент в представлении (активировать виджет редактирования и не закрывать его), то в диспетчере задач можно наблюдать стремительное увеличение расходуемой процессом памяти. Что конечно очень не хорошо. Ситуация не меняется если вместо QPixmap передавать QColor, QIcon...

Если же убрать ветку
case Qt::DecorationRole:
, то все работает нормально.

Может быть это БАГ, хотя такой расклад очень печален, ибо такой функционал часто бывает нужен. Если же нет помогите решить в чем дело.

Замечания:
1. Модель наследуется от QAbstractItemModel;
2. Представление использую QTreeView;
3. Делегат по умолчанию.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 8.5.2011, 21:32
Сообщение #2


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


компилируемое тестовое приложение прикрепи (zip-архив), потестю.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Lappu
  опции профиля:
сообщение 10.5.2011, 1:43
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 30.3.2011
Пользователь №: 2558

Спасибо сказали: 0 раз(а)




Репутация:   0  


Выкладываю пример приложения. Рассмотрите, пожалуйста. Очень мне это не нравится. Уже начинаю в сторону wxWidgets поглядывать для своего приложения.
Прикрепленные файлы
Прикрепленный файл  DispalayRoleProblem.zip ( 4.58 килобайт ) Кол-во скачиваний: 115
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 10.5.2011, 6:44
Сообщение #4


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Iron Lappu @ 10.5.2011, 4:43) *
Уже начинаю в сторону wxWidgets поглядывать для своего приложения.
слишком кардинально. Там сколько времени блох вылавливать будешь?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 10.5.2011, 8:36
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Цитата
в диспетчере задач можно наблюдать стремительное увеличение расходуемой процессом памяти.


Стремительное это как? У меня лично в среднем на 20 кб увеличивается при открытии делегата.
Память резко уменьшается когда приложение находится на фоне (например, когда окно свернуто в панель задач). Затем когда восстанавливаешь окно - то памяти уже не так много кушается.

Видимо в Qt при наступлении таких событий подчищается мусор.

Например, у меня после открытия проги (в релиз сборке) диспетчер показывает 9,5 мб.
Сворачиваю окно - 0,5 мб
Восстанавливаю - 4,5 мб
Путем множественных вызовов делегатов довожу объем памяти до 5 мб.
Сворачиваю окно - 0,5 мб
Восстанавливаю - 4,5 мб

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Lappu
  опции профиля:
сообщение 10.5.2011, 15:58
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 30.3.2011
Пользователь №: 2558

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата
Стремительное это как? У меня лично в среднем на 20 кб увеличивается при открытии делегата.

Стремительно - это так, что у меня в режиме редактирования (Когда виджет редактирования не закрыт. Не так что открыл и закрыл.) память растет безостановочно. Например, когда я открываю виджет, то память увеличивается на 148 Кб. Ну это ладно. Но если не закрывать виджет, то память продолжает увеличиваться. Прибавляет примерно 160-180 Кб/мин. И такое происходит каждый раз при открытии виджета. Разве это нормально?!
Цитата
слишком кардинально. Там сколько времени блох вылавливать будешь?

И много же там блох?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
PAFOS
  опции профиля:
сообщение 10.5.2011, 16:41
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 258
Регистрация: 27.12.2010
Из: Дмитров
Пользователь №: 2309

Спасибо сказали: 29 раз(а)




Репутация:   8  


Я кажется нашел в чем косяк.

У тебя при каждой перерисовке делегата (когда мигает курсор, делегат перерисовывается) создавался новый Pixmap, а удаление старого откладывалось на потом.

Решение:

я перенес создание pixmap в MyItem, вот что получилось:

myitem.h
Раскрывающийся текст
class MyItem
{
    MyItem *m_parent;
    QList<MyItem*> m_children;
    QVariant m_value;
    QString  m_name;
    QPixmap m_pixmap; // <==== теперь на один экземпляр MyItem будет один экземпляр QPixmap

public:
    MyItem();
    ~MyItem();

    MyItem *parent() const;
    int index() const;
    MyItem *child(int index) const;
    bool addChild(MyItem *item);
    int childrenCount() const;

    QPixmap pixmap() const; //  <==== вот тут поставил метод доступа
    QVariant value() const;
    void setValue(const QVariant &value);
    QString name() const;
    void setName(const QString &name);
};


myitem.cpp
Раскрывающийся текст
....

void MyItem::setValue(const QVariant &value)
{
    m_value = value;

    QColor color = value.value<QColor>();
    m_pixmap = QPixmap(16, 16);
    m_pixmap.fill(color);
}

QPixmap MyItem::pixmap() const
{
    return m_pixmap;
}

....


mymodel.cpp

Раскрывающийся текст
    case Qt::DecorationRole:
        {
            return pItem->pixmap();
        }

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 10.5.2011, 17:07
Сообщение #8


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Iron Lappu @ 10.5.2011, 18:58) *
И много же там блох?
не меньше чем в Qt. Как и в любой другой абширной библиотеке.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Lappu
  опции профиля:
сообщение 10.5.2011, 17:36
Сообщение #9


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 30.3.2011
Пользователь №: 2558

Спасибо сказали: 0 раз(а)




Репутация:   0  


Да есть такое дело! Проблема устраняется. Такой вариант я хотел попробовать, правда с указателем, но передумал по двум причинам:
1. Проследив за действиями, которые происходят с переданным QPixmap, подумал, что не дело не в этом. (Спасибо за то, что переубедил :) )
2. Я прикрепил пример просто описывающий проблему. В реальном же приложении помимо элементов имеющим значение QColor будет много других. (Что-то наподобие диспетчера св-в). И все будут объектами одного класса (наподобие MyItem). Поэтому не хотелось бы из-за одного варианта вводить в класс один метод и переменную, которые для всех остальных не нужны.
Добавлю, что во всех примерах, что я видел, это делалось также, как и в первоначальном варианте. Где-то и в документации было. Но раз объект QPixmap не удаляется должным образом, то опять вопрос - Значит баг?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Lappu
  опции профиля:
сообщение 10.5.2011, 19:01
Сообщение #10


Новичок


Группа: Новичок
Сообщений: 9
Регистрация: 30.3.2011
Пользователь №: 2558

Спасибо сказали: 0 раз(а)




Репутация:   0  


Дополнительные сведения:
Если передавать для роли Qt::DecorationRole вместо QPixmap объект QColor,
    case Qt::DecorationRole:
        {
            data = QVariant::fromValue(QColor(255, 0, 0));
            break;
        }

чтобы позволить делегату самостоятельно создавать соответствующий QPixmap, то картина не меняется.
Поэтому я это кроме как УТЕЧКОЙ памяти по-другому назвать пока не могу. Вроде именно так и предусматривается использовать эту роль, а не обязательно держать у себя объект QPixmap. Может для кого-то это не страшно, но мне это сильно не нравится! Попробую разобраться в исходниках, иначе придется использовать вариант предложенный PAFOS.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 25.4.2024, 23:37