crossplatform.ru

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

urdnot
  опции профиля:
сообщение 4.9.2014, 17:36
Сообщение #1


Новичок


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

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




Репутация:   0  


Имеется следующая функция ,которая вызывается посредствам выбора пункта контекстного меню MyQGraphicsItem:
void MyQGraphicsView::deleteItem(QGraphicsItem *item)
{
....
removeItem(item);
delete item;
....
}

При выполнении программы выскакивает Segfault. Похоже после вызова removeItem QGraphicsView почему-то пытается его перерисовать, но на тот момент я уже освободил память под item.
И вот как тут быть? Как удалить итем со сцены и освободить память.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
 
Начать новую тему
Ответов
urdnot
  опции профиля:
сообщение 5.9.2014, 10:51
Сообщение #2


Новичок


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

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




Репутация:   0  


Item Point:
Раскрывающийся текст
class Point : public QGraphicsItem
{
public:
    Point(const QPointF & p = QPointF(0,0), int pos = 0);

    void setIn(Line *e) { in = e; }
    void setOut(Line *e) { out = e; }
    QVariant itemChange(GraphicsItemChange change, const QVariant &value);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
               QWidget *widget);
private:
    Line * in, * out;

    int Position;
};

Point::Point(const QPointF & p, int pos) :
    in(nullptr),out(nullptr)
{
    setFlags(ItemIsMovable | ItemIsSelectable | ItemIgnoresTransformations | ItemSendsGeometryChanges);
    setCursor(Qt::PointingHandCursor);
    setZValue(pos);

    setPos(p);
    Position = pos;
}

QVariant Point::itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value)
{
    if(change == ItemPositionHasChanged && scene()) {
        if(in)
            in->adjust();
        if(out)
            out->adjust();
    }

    return QGraphicsItem::itemChange(change, value);
}

QRectF WayPoint::boundingRect() const
{
    return QRectF( -5, -5 ,10 ,10);
}

void WayPoint::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
     painter->drawEllipse(QRectF(-5, -5, 10,10));
}


Item Line:
Раскрывающийся текст
class Line : public QGraphicsItem
{
public:
    Line(Point *, Point *);

    void setStart(Point *);
    void setFinish(Point *);

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

private:
    Point *start, *finish;
};

Line::Line(Point *s, Point *f) :
    start(s), finish(f)
{
    s->setOut(this);
    f->setIn(this);

    setZValue(-2);
    
    adjust();
}

void Line::setStart(Point * start_)
{
    start = start_;
    start->setOut(this);

    adjust();
}

void Line::setFinish(Point * finish_)
{
    finish = finish_;
    finish->setIn(this);

    adjust();
}

QRectF Line::boundingRect() const
{
    return QRectF(start->pos(), finish->pos()).normalized().adjusted(-2,-2,2,2);
}

void Line::adjust()
{
    prepareGeometryChange();
}

void Line::paint(QPainter *painter, const QStyleOptionGraphicsItem */*option*/, QWidget */*widget*/)
{
    qreal q = scene()->views().at(0)->transform().m11();
    QPen pen(QColor(0, 145, 255), 5 * (1. / q));
    painter->setRenderHint(QPainter::Antialiasing);
    painter->setPen(pen);
    painter->drawLine(start->pos(), finish->pos());
}


И наконец MyGraphicsView:

Раскрывающийся текст
class MyGraphicsView : public QGraphicsView
{
    Q_OBJECT

public:
    MyGraphicsView(QWidget * parent = 0);
    ~MyGraphicsView();

public slots:
    void addPoint();
    void removePoint();

private:
    typedef QVector<Point *> p_vector;
    typedef QVector<Line *> line_vector;

    p_vector ps;
    line_vector lines;
};

void MyGraphicsView::addPoint(const QPointF & local)
{
    Point * p = new Point(local, ps.size() + 1);
    if(!ps.empty())
    {
        line * e = new Line(ps.back(), p);
        lines.push_back(e);
        scene()->addItem(e);
    }
    ps.push_back(p);
    scene()->addItem(p);
}

void MyGraphicsView::removePoint(int i)
{
    if(i <= 1)
    {
        auto it_p = ps.begin();
        scene()->removeItem(*it_p);
        delete *it_p;
        ps.erase(it_p);

        if(!lines.empty())
        {
            auto it_l = lines.begin();
            scene()->removeItem(*it_l);
            delete *it_l;
            lines.erase(it_l);
            (*(ps.begin()))->setIn(nullptr);
        }
    } else {
        if(i > 1 && i < wps.size())
        {
            auto it_p = ps.begin() + i - 1;
            auto it_l = lines.begin() + i - 2;

            scene()->removeItem(*it_p);
            scene()->removeItem(*it_l);
            scene()->removeItem(*(it_l + 1));
            delete *it_p;
            delete *it_l;
            delete *(it_l + 1);
            Line * e = new Line(*(it_p - 1),*(it_p + 1));
            (*it_l) = e;
            scene()->addItem(e);
            ps.erase(it_p);
            lines.erase(it_l + 1);
        } else {
            if(i >= ps.size())
            {
                auto it_p = ps.begin() + ps.size() - 1;
                scene()->removeItem(*it_p);
                delete *it_p;
                ps.erase(it_p);

                if(!lines.empty())
                {
                    auto it_l = lines.begin() + lines.size() - 1;
                    scene()->removeItem(*it_l);
                    delete *it_l;
                    lines.erase(it_l);
                    (*(ps.end() - 1))->setOut(nullptr);
                }
            }
        }
    }
}


Проблема в removePoint.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
FireBlack
  опции профиля:
сообщение 5.9.2014, 11:54
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 38
Регистрация: 17.10.2010
Из: г.Пенза
Пользователь №: 2121

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




Репутация:   1  


Цитата(urdnot @ 5.9.2014, 11:51) *
Проблема в removePoint.

Нет, проблема не там. После правок удалось скомпилить Ваш код - он полностью рабочий. Попробуйте пересобрать проект, предварительно удалив все сборочные файлы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме


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


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


RSS Рейтинг@Mail.ru Текстовая версия Сейчас: 3.7.2025, 22:12