Russian Qt Forum

Qt => Общие вопросы => Тема начата: frostyland от Июль 06, 2010, 14:44



Название: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: 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;
}

Как быть? Как приводить типы? И как красиво итерировать? Может я не так делаю???


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: frostyland от Июль 06, 2010, 15:08
Нарыл кастинг qgraphicsitem_cast<>()
Но и он тоже не дает нормально кастить.
Ошибка вылезает при доступе к полям объекта
Код:
void Chip::changeColor()
{
m_even = true;
}
В отладчике вот так вот красненько предупреждает о проблемах, видимо поэтому и ругается
(http://content.foto.mail.ru/mail/frost666/heap/i-185.jpg)

В чем косяк-то???


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: pastor от Июль 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.


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: frostyland от Июль 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...


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: frostyland от Июль 06, 2010, 15:50
Реализация virtual int type() const не помогла.
Все равно в отладчике вот красненько предупреждает о проблемах, как и двумя постами выше,
и в коде доступа к полям так же вываливается исключение.

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

ЗЫ. Еще бы она помогла... Она даже не вызывается.
Причем, чистил код, удалял Makefile.Debug, Makefile.Release, все равно...


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: lit-uriy от Июль 06, 2010, 16:04
>>и в коде доступа к полям так же вываливается исключение.
вообще-то принято проверять указатель на нуль, перед обращением к полям, после того как использовалось динамическое приведение типов.


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: frostyland от Июль 06, 2010, 21:09
>>и в коде доступа к полям так же вываливается исключение.
вообще-то принято проверять указатель на нуль, перед обращением к полям, после того как использовалось динамическое приведение типов.

Абсолютно верно.
Но что это меняет в данном случае, если я заведомо знаю, что там должны быть именно мои типы?
Если приведение возвращает нуль, значит, я что-то делаю неправильно. Не должно там быть нуля.
Или приведение не работает
Вот и возвращаемся к вопросу - что я делаю не так.


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: frostyland от Июль 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();
}
}


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: Igors от Июль 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();


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: frostyland от Июль 08, 2010, 06:13
Может все просто - m_scene->items() возвращает по значению безымянный объект, его деструктор  вызовется перед следующей строкой. Стоит попробовать
[/quote]

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


Название: Re: QGraphicsScene - как реализовать базовых указателей и доступ к ним?
Отправлено: Igors от Июль 08, 2010, 13:50
Не может быть. У Qt-итераторов в стиле C++ семантика как у STL, шаблонный параметр показывает, что там хранятся не объекты а указатели.
Эти указатели хранятся в QList который должен быть грохнут, т.к. выходит из контекста, и Вы итерируете уничтоженный QList. Проще посмотреть в отладчике  :)