Hello,
I'm experiencing a crash when, after applying a graphic effect on an item group, I try to remove from the scene that item group. The crash doesn't happen if I apply the effect to items of the group or if I don't use the effect at all.
I'm trying to create a scene with some items (with effect), and when a key is pressed, only a part of such items are deleted. I wrote this little demo (see below). Running it, I do some random clicks and press Escape. The application crash (SIGSEGV) on line 135 of qscopedpointer.h, function data.
Please, tell me if I'm doing something wrong or test if it works on your implementation, I'm using Qt 4.7.3 (64 bit).
Here's the code (removed the guards from the headers).
main.cpp
#include <QtGui/QApplication>
#include "mainwindow.hh"
int main(int argc, char *argv[]) {
MainWindow w;
w.show();
return a.exec();
}
#include <QtGui/QApplication>
#include "mainwindow.hh"
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
To copy to clipboard, switch view to plain text mode
itemfieldeffect.hh
#include <QtGui>
class ItemFieldEffect: public QGraphicsEffect {
public:
ItemFieldEffect(qreal radius);
private:
qreal _radius;
};
#include <QtGui>
class ItemFieldEffect: public QGraphicsEffect {
public:
ItemFieldEffect(qreal radius);
void draw(QPainter *painter);
QRectF boundingRectFor(const QRectF &sourceRect) const;
private:
qreal _radius;
};
To copy to clipboard, switch view to plain text mode
itemfieldeffect.cpp
#include "itemfieldeffect.hh"
ItemFieldEffect::ItemFieldEffect(qreal radius):
_radius(radius) {
}
void ItemFieldEffect
::draw(QPainter *painter
) { painter->save();
grad.
setColorAt(0,
QColor(0,
0,
0,
200));
grad.
setColorAt(1.0,
QColor(0,
0,
0,
30));
painter
->setBrush
(QBrush(grad
));
painter->setPen(Qt::NoPen);
painter->drawEllipse(-_radius, -_radius, _radius * 2, _radius * 2);
painter->restore();
drawSource(painter);
}
QRectF ItemFieldEffect
::boundingRectFor(const QRectF &sourceRect
) const { return sourceRect.adjusted(-_radius, -_radius, _radius, _radius);
}
#include "itemfieldeffect.hh"
ItemFieldEffect::ItemFieldEffect(qreal radius):
_radius(radius) {
}
void ItemFieldEffect::draw(QPainter *painter) {
painter->save();
QRadialGradient grad(0, 0, _radius);
grad.setSpread(QGradient::PadSpread);
grad.setColorAt(0, QColor(0, 0, 0, 200));
grad.setColorAt(1.0, QColor(0, 0, 0, 30));
painter->setBrush(QBrush(grad));
painter->setPen(Qt::NoPen);
painter->drawEllipse(-_radius, -_radius, _radius * 2, _radius * 2);
painter->restore();
drawSource(painter);
}
QRectF ItemFieldEffect::boundingRectFor(const QRectF &sourceRect) const {
return sourceRect.adjusted(-_radius, -_radius, _radius, _radius);
}
To copy to clipboard, switch view to plain text mode
mainwindow.hh
#include <QtGui>
Q_OBJECT
public:
private:
};
#include <QtGui>
class MainWindow: public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
bool eventFilter(QObject *target, QEvent *event);
QGraphicsItem *createPoint(const QPointF &pos, const QString &label);
private:
QGraphicsView *_gv;
QGraphicsScene *_gs;
QMap<QString, QGraphicsItem *> _visiblePoints;
};
To copy to clipboard, switch view to plain text mode
mainwindow.cpp
#include "mainwindow.hh"
#include "itemfieldeffect.hh"
MainWindow
::MainWindow(QWidget *parent
) setCentralWidget(_gv);
_gv->setScene(_gs);
_gv->installEventFilter(this);
}
bg
->setBrush
(QColor::fromRgb(255,
244,
194,
220));
lab->setPlainText(label);
bg->setRect(lab->boundingRect());
qreal x = bg->rect().width() / -2.0;
qreal y = bg->rect().height() / -2.0;
bg->setPos(x, y);
lab->setPos(x, y);
grp->setPos(pos);
grp->setGraphicsEffect(new ItemFieldEffect(50));
return grp;
}
if (target == _gv) {
switch (event->type()) {
_gv->setSceneRect(0, 0, re->size().width(), re->size().height());
break;
}
case QEvent::MouseButtonPress: { static int counter = 0;
_gs->addItem(it);
if (counter % 2)
_visiblePoints.insert(id, it);
break;
}
QKeyEvent *ke
= static_cast<QKeyEvent
*>
(event
);
if (ke->key() == Qt::Key_Escape) {
foreach
(QString id, _visiblePoints.
keys()) _gs->removeItem(_visiblePoints.value(id));
_visiblePoints.clear();
}
break;
}
default: { }
}
}
return false;
}
#include "mainwindow.hh"
#include "itemfieldeffect.hh"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) {
_gv = new QGraphicsView(this);
setCentralWidget(_gv);
_gs = new QGraphicsScene(this);
_gv->setScene(_gs);
_gv->installEventFilter(this);
}
QGraphicsItem *MainWindow::createPoint(const QPointF &pos, const QString &label) {
QGraphicsItemGroup *grp = new QGraphicsItemGroup;
QGraphicsEllipseItem *bg = new QGraphicsEllipseItem(grp);
grp->setFlags(QGraphicsItem::ItemIsSelectable);
bg->setBrush(QColor::fromRgb(255, 244, 194, 220));
QGraphicsTextItem *lab = new QGraphicsTextItem(grp);
lab->setPlainText(label);
bg->setRect(lab->boundingRect());
qreal x = bg->rect().width() / -2.0;
qreal y = bg->rect().height() / -2.0;
bg->setPos(x, y);
lab->setPos(x, y);
grp->setPos(pos);
grp->setGraphicsEffect(new ItemFieldEffect(50));
return grp;
}
bool MainWindow::eventFilter(QObject *target, QEvent *event) {
if (target == _gv) {
switch (event->type()) {
case QEvent::Resize: {
QResizeEvent *re = static_cast<QResizeEvent *>(event);
_gv->setSceneRect(0, 0, re->size().width(), re->size().height());
break;
}
case QEvent::MouseButtonPress: {
QMouseEvent *me = static_cast<QMouseEvent *>(event);
QPointF pos = me->posF();
static int counter = 0;
QString id = QString("%1").arg(++counter);
QGraphicsItem *it = createPoint(pos, id);
_gs->addItem(it);
if (counter % 2)
_visiblePoints.insert(id, it);
break;
}
case QEvent::KeyPress: {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Escape) {
foreach (QString id, _visiblePoints.keys())
_gs->removeItem(_visiblePoints.value(id));
_visiblePoints.clear();
}
break;
}
default: { }
}
}
return false;
}
To copy to clipboard, switch view to plain text mode
Any feedback appreciated.
Thanks
~Aki
Bookmarks