
Originally Posted by
high_flyer
In the view?
Yes.
I would expect in the widget - since the mouse events go through the proxy to the widget, which I guess then consumes it.
But for the events to reach the proxy, they have to go through the view
And since it's the item that handles the ItemIsMovable flag, you'd have to reimplement the proxy widget or catch the event earlier.
I'd expect that if the widget returns 'false' on the event handler the proxy could continue to act on the event with its regular graphics item behavior...
Am I wrong with this theory?
I think you are wrong. Yesterday I thought the same so I checked with a widget (QGroupBox, I think) that doesn't handle mouse events (so it should ignore the event) and it was not movable.
Let's look at the code...
{
if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
if (!multiSelect) {
if (!d_ptr->selected) {
++scene->d_func()->selectionChanging;
scene->clearSelection();
--scene->d_func()->selectionChanging;
}
setSelected(true);
}
}
} else if (!(flags() & ItemIsMovable)) {
event->ignore();
}
if (d_ptr->isWidget) {
// Qt::Popup closes when you click outside.
QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
event->accept();
if (!w->rect().contains(event->pos()))
w->close();
}
}
}
void QGraphicsItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
if (event->button() == Qt::LeftButton && (flags() & ItemIsSelectable)) {
bool multiSelect = (event->modifiers() & Qt::ControlModifier) != 0;
if (!multiSelect) {
if (!d_ptr->selected) {
if (QGraphicsScene *scene = d_ptr->scene) {
++scene->d_func()->selectionChanging;
scene->clearSelection();
--scene->d_func()->selectionChanging;
}
setSelected(true);
}
}
} else if (!(flags() & ItemIsMovable)) {
event->ignore();
}
if (d_ptr->isWidget) {
// Qt::Popup closes when you click outside.
QGraphicsWidget *w = static_cast<QGraphicsWidget *>(this);
if ((w->windowFlags() & Qt::Popup) == Qt::Popup) {
event->accept();
if (!w->rect().contains(event->pos()))
w->close();
}
}
}
To copy to clipboard, switch view to plain text mode
{
Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
qDebug() << "QGraphicsProxyWidget::mousePressEvent";
#endif
d->sendWidgetMouseEvent(event);
}
void QGraphicsProxyWidget::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QGraphicsProxyWidget);
#ifdef GRAPHICSPROXYWIDGET_DEBUG
qDebug() << "QGraphicsProxyWidget::mousePressEvent";
#endif
d->sendWidgetMouseEvent(event);
}
To copy to clipboard, switch view to plain text mode
See? QGraphicsProxyWidget unconditionally transfers the event to the widget.
However if you ignore it (as you suggested) the proxy should ignore it as well:
{
mouseEvent.setPos(event->pos());
mouseEvent.setScreenPos(event->screenPos());
mouseEvent.setButton(Qt::NoButton);
mouseEvent.setButtons(0);
mouseEvent.setModifiers(event->modifiers());
sendWidgetMouseEvent(&mouseEvent);
event->setAccepted(mouseEvent.isAccepted());
}
void QGraphicsProxyWidgetPrivate::sendWidgetMouseEvent(QGraphicsSceneHoverEvent *event)
{
QGraphicsSceneMouseEvent mouseEvent(QEvent::GraphicsSceneMouseMove);
mouseEvent.setPos(event->pos());
mouseEvent.setScreenPos(event->screenPos());
mouseEvent.setButton(Qt::NoButton);
mouseEvent.setButtons(0);
mouseEvent.setModifiers(event->modifiers());
sendWidgetMouseEvent(&mouseEvent);
event->setAccepted(mouseEvent.isAccepted());
}
To copy to clipboard, switch view to plain text mode
... but the event won't reach the code responsible for moving the item which was overridden by reimplementing mouse events in the proxy widget. So again, it's either subclassing QGraphicsProxyWidget or QGraphicsView.
This also explains that setting the scene size to whatever the OP set it couldn't have made the items move
Bookmarks