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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Segmentation fault при итерации QGraphicsItemGroup.childItems()  (Прочитано 4821 раз)
Mist1K
Гость
« : Июнь 20, 2014, 10:24 »

Делаю игру в которой надо складывать картинку из частей. При стыковке двух элементов наследников класса QGraphicsItem объединяю их в класс наследник QGraphicsItemGroup. При перемещении группы каждому члену группы меняю координаты для отслеживания их позиции на сцене, при этом иногда получаю вылет "Segmentation fault"  Грустный и не вижу где косяк, помогите пожалуйста разобраться.

main.cpp
Код:
#include "mygi.h"
#include "mygig.h"
#include <QtWidgets>

int main(int argc, char *argv[]){
    QApplication a(argc, argv);

    QGraphicsScene scene;
    scene.setSceneRect(0, 0, 500, 500);

    MyGIG* group = new MyGIG();
    for ( int i = 0; i < 4; i++ ) {
        MyGI* item = new MyGI();
        item->setPos(i*100, 0);
        group->addToGroup(item);
        qDebug() << item;
    }
    group->setFlag(QGraphicsItem::ItemIsMovable);
    scene.addItem(group);

    QGraphicsView view(&scene);
    view.show();

    return a.exec();
}

mygi.h
Код:
#ifndef MYGI_H
#define MYGI_H

#include <QGraphicsItem>

class MyGI : public QGraphicsItem {
    public:
        MyGI();
        ~MyGI();

        QRectF boundingRect() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
};

#endif // MYGI_H

mygi.cpp
Код:
#include "mygi.h"
#include "ui_mygi.h"
#include <QPainter>

MyGI::MyGI() {}

MyGI::~MyGI() {}

QRectF MyGI::boundingRect() const {
    return QRectF(0, 0, 100, 100);
}

void MyGI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
    painter->setPen(Qt::black);
    painter->drawRect(0, 0, 100, 100);
}

mygig.h
Код:
#ifndef MYGIG_H
#define MYGIG_H

#include <QGraphicsItemGroup>

class MyGIG : public QGraphicsItemGroup {
    public:
        MyGIG();
        void mouseReleaseEvent(QGraphicsSceneMouseEvent * event);
};

#endif // MYGIG_H

mygig.cpp
Код:
#include "mygig.h"
#include <qdebug.h>

MyGIG::MyGIG() {}

void MyGIG::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
    QGraphicsItemGroup::mouseReleaseEvent(event);
    for ( QList<QGraphicsItem*>::iterator it = childItems().begin(); it != childItems().end(); ++it ) {
        qDebug() << (*it);
        (*it)->moveBy(pos().x(), pos().y()); // Segmentation fault
    }
    setPos(0, 0);
}

PS: Буду благодарен за любые предложения, замечания, советы.
Записан
Bepec
Гость
« Ответ #1 : Июнь 20, 2014, 10:46 »

QGraphicsItemGroup::mouseReleaseEvent(event);
А вы уверены что после этой строчки event уже не удалён? Улыбающийся
Записан
Mist1K
Гость
« Ответ #2 : Июнь 20, 2014, 11:04 »

QGraphicsItemGroup::mouseReleaseEvent(event);
А вы уверены что после этой строчки event уже не удалён? Улыбающийся

Да я на самом деле мало в чем уверен)
Среду разработки Qt использую впервые и изучаю по ходу необходимости.

Код:
void MyGIG::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
    for ( QList<QGraphicsItem*>::iterator it = childItems().begin(); it != childItems().end(); ++it ) {
        qDebug() << (*it);
        (*it)->moveBy(pos().x(), pos().y()); // Segmentation fault
    }
    setPos(0, 0);
    QGraphicsItemGroup::mouseReleaseEvent(event);
}

перестановка мест слагаемых сумму не изменило(
Записан
Bepec
Гость
« Ответ #3 : Июнь 20, 2014, 11:21 »

Вы ещё пару раз строчки поменяйте, мб поможет? Веселый Издеваюсь конечно, извините Улыбающийся

Проверку там сделайте на NULL.

PS и вообще хватит ребячиться - breakpoint тудыть и пошагово смотрите что происходит и проверяй всё. Хотя б место вылета уточните.
Записан
Swa
Самовар
**
Offline Offline

Сообщений: 170


Просмотр профиля
« Ответ #4 : Июнь 20, 2014, 11:38 »

Вообщем, я опытным путем выяснил, что список, полученный через childItems()  - одноразовый, и при вызове этого метода старые указатели на детей, полученные этим методом, инвалидируются.
Такой код работает:
Код:
QList<QGraphicsItem*> list = childItems();

for (QList<QGraphicsItem*>::iterator iter = list.begin(); iter != list.end(); iter++ ) {
qDebug() << (*iter);
(*iter)->moveBy(pos().x(), pos().y());
}
Записан
Mist1K
Гость
« Ответ #5 : Июнь 20, 2014, 11:45 »

Вообщем, я опытным путем выяснил, что список, полученный через childItems() - одноразовый, и при вызове этого метода старые указатели на детей, полученные этим методом, инвалидируются.

Спасибище! Уж не знаю сколько я бы еще ковырялся без вашей помощи...
« Последнее редактирование: Июнь 20, 2014, 12:00 от Mist1K » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #6 : Июнь 20, 2014, 14:48 »

Вообщем, я опытным путем выяснил, что список, полученный через childItems()  - одноразовый, и при вызове этого метода старые указатели на детей, полученные этим методом, инвалидируются.
А без опытов просто взять и посмотреть прототип функции?
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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