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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: QGraphicsScene - как реализовать базовых указателей и доступ к ним?  (Прочитано 5304 раз)
frostyland
Гость
« : Июль 06, 2010, 14:44 »

Приветствую!

В моем случае на сцене хранится набор указателей на элементы, наследованные от QGraphicsItem.
Необходимо пробегаться и приводить к реальным типам.
Как быть?

Код таков (тестовый поэтому корявый)

Код:
		QList<QGraphicsItem*>::iterator it = m_scene->items().begin();
bool _b = false;
for (; it != m_scene->items().end(); ++it) {
_b = !_b;
QGraphicsItem* _item = *it;
Chip* _chip = dynamic_cast<Chip*>(_item);
// Chip* _chip = static_cast<Chip*>(_item);
if(_b)
_chip->changeColor();
else
_chip->restoreColor();
}

Вываливается вот такая ошибка
Цитировать
---------------------------
Получен сигнал
---------------------------
Приложение остановлено, так как оно получило сигнал от операционной системы.
Сигнал: SIGSEGV
Назначение:Segmentation fault
---------------------------

Метод dynamic_cast выдает ошибку сегментирования прямо в момент применения
Метод static_cast проходит, но ошибка вываливается в коде

Код:
void Chip::changeColor()
{
m_even = true;
}

Как быть? Как приводить типы? И как красиво итерировать? Может я не так делаю???
Записан
frostyland
Гость
« Ответ #1 : Июль 06, 2010, 15:08 »

Нарыл кастинг qgraphicsitem_cast<>()
Но и он тоже не дает нормально кастить.
Ошибка вылезает при доступе к полям объекта
Код:
void Chip::changeColor()
{
m_even = true;
}
В отладчике вот так вот красненько предупреждает о проблемах, видимо поэтому и ругается


В чем косяк-то???
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #2 : Июль 06, 2010, 15:18 »

Цитировать
T qgraphicsitem_cast ( QGraphicsItem * item )

Note: To make this function work correctly with custom items, reimplement the type() function for each custom QGraphicsItem subclass.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
frostyland
Гость
« Ответ #3 : Июль 06, 2010, 15:33 »

Вот емае (((
Так это косячно!
Код:
class CustomItem : public QGraphicsItem
 {
    ...
    [b]enum { Type = UserType + 1 };[/b]

    [b]int [/b]type() const
    {
        // Enable the use of qgraphicsitem_cast with this item.
        return Type;
    }
    ...
 };

То есть, надо держать в голове и постоянно отслеживать неперекрывающиеся значения type(). А если дополнения в плагинах? Да мало ли что...
ммм... косячно...

ВОт пытаюсь унаследоваться и от QObject, чтобы использовать qobject_cast
Лезут ошибки
Код:
undefined reference to vtable

А это что еще такое??? 0_0

---------------------- ДОБАВЛЕНО ----------------------------
 Ну я победил это, вычистив каталог, пересобрав и получив наконец внятную просьбу компилятора добавить
Q_INTERFACES(QGraphicsItem)

Но это не решило проблемы.
Так как в этом коде
Код:
QGraphicsItem* _item = *it;
Chip* _chip = qobject_cast<Chip*>(_item);

нельзя кастить QGraphicsItem средством qobject_cast, ибо он НЕ ОТ QQbject

Надо искать workaround...
« Последнее редактирование: Июль 06, 2010, 15:40 от frostyland » Записан
frostyland
Гость
« Ответ #4 : Июль 06, 2010, 15:50 »

Реализация virtual int type() const не помогла.
Все равно в отладчике вот красненько предупреждает о проблемах, как и двумя постами выше,
и в коде доступа к полям так же вываливается исключение.

Может, пробегаться по элементам сцены надо как-то иначе? Кто сталкивался???

ЗЫ. Еще бы она помогла... Она даже не вызывается.
Причем, чистил код, удалял Makefile.Debug, Makefile.Release, все равно...
« Последнее редактирование: Июль 06, 2010, 15:57 от frostyland » Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Июль 06, 2010, 16:04 »

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

Юра.
frostyland
Гость
« Ответ #6 : Июль 06, 2010, 21:09 »

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

Абсолютно верно.
Но что это меняет в данном случае, если я заведомо знаю, что там должны быть именно мои типы?
Если приведение возвращает нуль, значит, я что-то делаю неправильно. Не должно там быть нуля.
Или приведение не работает
Вот и возвращаемся к вопросу - что я делаю не так.
Записан
frostyland
Гость
« Ответ #7 : Июль 07, 2010, 07:26 »

Посмотрел в демках Qt Creator - везде используется foreach.
С ним работает и у меня.

Код:
		QList<QGraphicsItem*> _all;
_all = m_scene->items();
foreach (QGraphicsItem *item, _all) {
Chip* _chip = qgraphicsitem_cast<Chip*>(item);
if (_chip){
_chip->changeColor();
}
}
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июль 07, 2010, 15:18 »

Код:
		QList<QGraphicsItem*>::iterator it = m_scene->items().begin();
Может все просто - m_scene->items() возвращает по значению безымянный объект, его деструктор  вызовется перед следующей строкой. Стоит попробовать

Код:
QList<QGraphicsItem*> theList = m_scene->items();
QList<QGraphicsItem*>::iterator it = theList.begin();
Записан
frostyland
Гость
« Ответ #9 : Июль 08, 2010, 06:13 »

Может все просто - m_scene->items() возвращает по значению безымянный объект, его деструктор  вызовется перед следующей строкой. Стоит попробовать
[/quote]

Не может быть. У Qt-итераторов в стиле C++ семантика как у STL, шаблонный параметр показывает, что там хранятся не объекты а указатели.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #10 : Июль 08, 2010, 13:50 »

Не может быть. У Qt-итераторов в стиле C++ семантика как у STL, шаблонный параметр показывает, что там хранятся не объекты а указатели.
Эти указатели хранятся в QList который должен быть грохнут, т.к. выходит из контекста, и Вы итерируете уничтоженный QList. Проще посмотреть в отладчике  Улыбающийся
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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