![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Любитель |
|
||||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Упрощенно говоря имеем в классе некоторого виджета графикс-вью (graphicsView_) и прайват-функцию createScene, которая заполняет сцену всякой ерундой. В числе прочего там есть кнопочка, щелчок по которой должен вызщвать пересоздание сцены. Кнопка (отдельный класс график-итемов) обрабатывает нажатие/отпуск мыхи и т. д.
Вариант 1: просто создаём новую сцену и устанавливаем её во вью. Работает. Но память всех сцен освобождается только после разрушение рассматриваемого виджета (он выступает парентом для сцен). Впрочем сие логично, но затратно. Вариант 2: что-то такое:
Сие не работает. Точнее, работает, если рекреат сцены инициируется внешним способом, но не кликом по кнопке сцены. После mouseReleasedEvent куте инициирует хаувер-события (точно не смотрел что именно). Причём даже когда на сцене нет ни одного итема, аксептющего хауверы (по видимому этот аксепт работает как обычный ивент-филтер). Так как сцены к тому моменту не существует, то this сцены получается не валидный. В итоге получаем вылет. Вариант 3: типа такого:
Сие работает. Но: 1. Не красиво выглядит. Почему я не нашёл у сцены методов вроде rest, removeAllItems или clear (или ночью глаза плохо видят в асистенете?) ??? 2. Память (по таск-менеджеру) после рекреата сцены все равно прибавляется. На 4-5 рекреатах - ничего, а потом потихоньку начинает тормозить (память идёт под 100 мегабайт). Правда, там ещё тупанул в одном месте (дома исправлю) - пиксмэпы на кнопках создаются каждый раз заново (на сцене много кнопок с одной картинкой). Пожалуй, надо статик-мембер завести. Насколько я помню, копирование QPixmap ведёт к shared-доступу. Но всё же к увеличению используемой памяти это не должно вести (кол-во кнопок старой и новой сцены всегда почти совпадает). Как лучше всего рекреатить сцену? Ваши мнения? |
||||
|
|||||
JackYF |
|
|||
![]() полуавантюрист ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 5814 Регистрация: 28.8.2004 Где: страна тысячи озё р Репутация: 18 Всего: 162 |
Вариант 3, завернутый в отдельную функцию и сделанный while' ом:
|
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
JackYF, сие не сработает - ты получишь вечный цикл (ты не удаляешь элемент из списка).
Что касается отдельной функции - это и есть recreateScene(). Оставил последний вариант, ошибка оказалась в другом. Когда я писал createScene, я считал, что сцена новая и коннектил некоторые сигнал/слоты (в том числе рекреат). Я просто упростил здесь задачу (в принципе на кнопках висят более масштабные действия, некоторые из которых в некоторых случаях вызывают сигнал, на который законнектен рекреат). Короче, в итоге на один мой класс, коннектилось при рекреате слот этого же рекреата. В итоге с каждым рекреатом росло кол-во его вызовов при следующем клике по кнопке. Проверив, сию ситуацию от ошибки избавился (память по-видимому шла под хранение коннектов и прочие кутешные вещи - сейчас всё чисто). |
|||
|
||||
zabivator |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 171 Регистрация: 7.6.2006 Где: нск Репутация: 1 Всего: 2 |
Любитель, вот за это плюс поставить можно! Вдохновил!
--------------------
#include <zabivator>int main( int, char * [] ){ while( Zabivator::жив() ) Zabivator::моск()++; return 0;} |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Начинаем флуд.
Честно - не понял чем (хотя б в каком посте). |
|||
|
||||
zabivator |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 171 Регистрация: 7.6.2006 Где: нск Репутация: 1 Всего: 2 |
Любитель, QGraphicsScene - видел столько раз эту шнягу в ассистансе. Но когда сейчас увидел код в его использованием... прозрел, что это ведь на самом деле очень-очень вкусно!
--------------------
#include <zabivator>int main( int, char * [] ){ while( Zabivator::жив() ) Zabivator::моск()++; return 0;} |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Да, кстати, вариант с непереприсваиванием списка итемов (при рекреате) не прокатит и в модифицированном варианте. Когда мы будем удалять первый элемент из списка (для списка это достаточно эффективно) или итерировать по нему (вместо условия isEmpty). Точнее в исключительных случаях это сработает, но в большинстве (в т. ч. у меня) - нет.
Почему? Объясняю. В куте кругом используется простая концепция парентов, реализованная на уровне QObject. Деструктор парента удаляет все свои child-итема. QGRaphicsItem не является наследником QObject, но там реализуется подобная вещь. У итема есть сцена к которой он относится и есть парентовый график-итем. Последний может быть нулевым указателем. В этом случае итем делитит сцена. Метод items вернёт все итемы. В итоге мы можем долбануть родителя, его дети тоже подохнут, но указатели на них (уже невалидные) останутся. Мы будем долбать и их. Сие вызовет вылет. Посему останавливаюсь на прошлом варианте. Правда, что тупанул - явно удалял элемент из сцены. С этим прекрасно справляется его деструктор. Если не нравиться выход посередине. Можно просто искуственно размножить начало цикла (благо оно в одну строчку):
Пожалуй этот вариант даже эстетичней. Даже в чистом виде потерь между двойным написанием кода почти нет. 90% компилер в состоянии скомпилировать сие с фактическим выходом посередине. |
|||
|
||||
Любитель |
|
|||
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Вопрос решён.
|
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |