Происходит вызов метода mouseMoveEvent объекта QGraphicsItem после вызова контекстного меню
У меня есть реализация класса Square
, основанная на QGraphicsItem
.
Класс реализован таким образом, что я мог перемещать объект в QGraphicsView.
Далее я создаю контекстное меню для объекта Square
в классе GraphicsView. Проблема в том, что после того, как я нажимаю на пункт меню, а затем на произвольную область сцены левой кнопкой мыши, объект, на который я нажал, перемещается на это место.
Хотя по идее этого не должно происходить. Как решить эту проблему?
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
explicit GraphicsView(QWidget* parent = nullptr)
: QGraphicsView(parent)
{
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, &GraphicsView::customContextMenuRequested, this, &GraphicsView::showContextMenu);
scene = new QGraphicsScene(this);
scene->setBackgroundBrush(Qt::white);
setScene(scene);
auto square = new Square();
square->setPos(10, 10);
scene->addItem(square);
auto square2 = new Square();
square2->setPos(50, 50);
scene->addItem(square2);
}
~GraphicsView() override = default;
void showContextMenu(const QPoint& pos)
{
auto position = QPoint(pos);
QGraphicsItem* item = scene->itemAt(mapToScene(pos), QTransform());
if (item && dynamic_cast<Square*>(item))
{
QMenu contextMenu(tr("Context menu1"), this);
QAction addBt1(tr("Btn1"), this);
connect(&addBt1, &QAction::triggered, this, &GraphicsView::addBtn1);
contextMenu.addAction(&addBt1);
QAction addBtn2(tr("Btn2"), this);
connect(&addBtn2, &QAction::triggered, this, &GraphicsView::addBtn2);
contextMenu.addAction(&addBtn2);
contextMenu.exec(mapToGlobal(pos));
}
}
static void addBtn1()
{
qDebug() << "Btn1";
}
static void addBtn2()
{
qDebug() << "Btn2";
}
QGraphicsScene* scene;
};
class Square : public QObject, public QGraphicsItem
{
Q_OBJECT
public:
explicit Square(QObject* parent = nullptr) : QObject(parent), QGraphicsItem() {}
~Square() {}
private:
QRectF boundingRect() const override { return {-3,-3,6,6}; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
painter->setPen(Qt::black);
painter->setBrush(Qt::green);
painter->drawRect(-3,-3,6,6);
Q_UNUSED(option);
Q_UNUSED(widget);
}
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
{
auto newPosition = mapToScene(event->pos());
QPointF positionMirrorDifference = newPosition - this->pos();
this->setPos(newPosition);
}
void mousePressEvent(QGraphicsSceneMouseEvent *event) override { Q_UNUSED(event); }
void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override { Q_UNUSED(event); }
};
Ответы (1 шт):
Автор решения: Alexander Chernin
→ Ссылка
По идее надо делать вот так:
class Square : public QObject, public QGraphicsItem
{
//...
private:
// Этим методом вы задаете границы объекта относительно его положения на сцене
QRectF boundingRect() const override {
// Позиция на сцене
QPointF p = this->pos();
return {
p.x() - 3, //
p.y() -3,
6,
6
};
}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override
{
painter->setPen(Qt::black);
painter->setBrush(Qt::green);
// Рисуем квадрат
painter->drawRect(boundingRect());
Q_UNUSED(option);
Q_UNUSED(widget);
}
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override
{
// Перемещаем в позицию event.pos() в координатах сцены
this->setPos(event->pos());
}
//...
};